Skip to content

airflowctl connections import fails when JSON omits extra field (type mismatch) #62653

Description

@Leondon9

Apache Airflow version

main (development)

What happened?

airflowctl connections import fails with a cryptic Pydantic ValidationError when the input JSON does not include an extra field for a connection.

The root cause is in connection_command.py:57:

extra=v.get("extra", {}),

When the extra key is absent from the JSON, v.get("extra", {}) returns {} (an empty dict). However, the ConnectionBody model defines extra as str | None (line 226 in generated.py):

extra: Annotated[str | None, Field(title="Extra")] = None

Pydantic rejects the dict with: Input should be a valid string [type=string_type, input_value={}, input_type=dict]

The fix is straightforward: change v.get("extra", {}) to v.get("extra"), which returns None when the key is absent — matching the model's str | None type.

What you think should happen instead?

A connection JSON without an extra field should import successfully, since extra is an optional field (str | None = None) in the model.

How to reproduce

# Create a minimal connection JSON without 'extra' field
echo '{"my_conn": {"conn_type": "postgres", "host": "localhost", "port": 5432}}' > /tmp/test_conn.json
airflowctl connections import /tmp/test_conn.json

Actual result:

Failed to import connections: 1 validation error for ConnectionBody
extra
  Input should be a valid string [type=string_type, input_value={}, input_type=dict]

Expected result:

Successfully imported 1 connection(s)

Verification (standalone Pydantic test confirming the behavior):

from pydantic import BaseModel, Field, ConfigDict
from typing import Annotated, Optional

class ConnectionBody(BaseModel):
    model_config = ConfigDict(extra="forbid")
    connection_id: Annotated[str, Field()]
    conn_type: Annotated[str, Field()]
    extra: Annotated[Optional[str], Field()] = None

# FAILS - current behavior (default={})
ConnectionBody(connection_id="test", conn_type="postgres", extra={})
# => ValidationError: Input should be a valid string

# WORKS - correct behavior (default=None)
ConnectionBody(connection_id="test", conn_type="postgres", extra=None)
# => OK

Operating System

Linux

Versions of Apache Airflow Providers

N/A

Deployment

Other

Deployment details

Breeze development environment

Anything else?

The extra field in Airflow connections stores a JSON string (e.g., '{"ssl": true}'). When omitted from the import JSON, the default should be None, not {}.

Code referenceairflow-ctl/src/airflowctl/ctl/commands/connection_command.py:49-61

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions