Leondon9 opened a new issue, #62653:
URL: https://github.com/apache/airflow/issues/62653

   ### 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`:
   ```python
   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`):
   ```python
   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
   
   ```bash
   # 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):
   ```python
   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 reference** — 
`airflow-ctl/src/airflowctl/ctl/commands/connection_command.py:49-61`
   
   ### Are you willing to submit PR?
   
   - [X] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [X] I agree to follow this project's [Code of 
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to