This is an automated email from the ASF dual-hosted git repository.

pierrejeambrun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 41bd4cd4427 Fix serializer for empty string extra connection (#65014)
41bd4cd4427 is described below

commit 41bd4cd4427bad33516909910984164dd4cd7c93
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Tue Apr 14 14:58:14 2026 +0200

    Fix serializer for empty string extra connection (#65014)
    
    * Fix serializer for empty string extra connection
    
    * Update 
airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
    
    Co-authored-by: Copilot <[email protected]>
    
    ---------
    
    Co-authored-by: Copilot <[email protected]>
---
 .../airflow/api_fastapi/core_api/datamodels/connections.py  |  8 ++++----
 .../api_fastapi/core_api/routes/public/test_connections.py  | 13 +++++++++++++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py 
b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
index a44edb5b91b..0b69c47cfdf 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
@@ -53,16 +53,16 @@ class ConnectionResponse(BaseModel):
     @field_validator("extra", mode="before")
     @classmethod
     def redact_extra(cls, v: str | None) -> str | None:
-        if v is None:
-            return None
+        if v is None or v == "":
+            return v
         try:
             extra_dict = json.loads(v)
             redacted_dict = redact(extra_dict)
             return json.dumps(redacted_dict)
         except json.JSONDecodeError:
             # Do not return un-redacted extra because this could cause 
sensitive information to be exposed.
-            # This code path should never been hit as 
``Connection._validate_extra`` sure that ``extra`` is
-            # always a valid JSON string. We add this safeguard just in case 
and to make the coupling
+            # This code path should never be hit as 
``Connection._validate_extra`` makes sure that ``extra`` is
+            # always a valid JSON string (if truthy). We add this safeguard 
just in case and to make the coupling
             # explicit.
             raise ValueError(
                 "This code path should never happen as persisted Connections 
(DB layer) should always enforce `extra` as a JSON string."
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
index 1f63247cfa9..4ca21b0ff49 100644
--- 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
+++ 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_connections.py
@@ -168,6 +168,19 @@ class TestGetConnection(TestConnectionEndpoint):
         assert body["conn_type"] == TEST_CONN_TYPE
         assert body["extra"] == '{"extra_key": "extra_value"}'
 
+    @pytest.mark.parametrize("extra_value", [None, ""])
+    def test_get_should_respond_200_with_empty_extra(self, test_client, 
session, extra_value):
+        """Empty string or NULL extra should not break serialization 
(regression test for #64950)."""
+        self.create_connection()
+        connection = session.scalars(select(Connection)).first()
+        connection.extra = extra_value
+        session.commit()
+        response = test_client.get(f"/connections/{TEST_CONN_ID}")
+        assert response.status_code == 200
+        body = response.json()
+        assert body["connection_id"] == TEST_CONN_ID
+        assert body["extra"] == extra_value
+
     @pytest.mark.enable_redact
     def test_get_should_respond_200_with_extra_redacted(self, test_client, 
session):
         self.create_connection()

Reply via email to