This is an automated email from the ASF dual-hosted git repository.
kaxilnaik 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 e4ea69c68dc Fall back to stringification for XCom (#55880)
e4ea69c68dc is described below
commit e4ea69c68dc18641a94ae8e2675855b365679d32
Author: Tzu-ping Chung <[email protected]>
AuthorDate: Fri Sep 19 22:29:55 2025 +0900
Fall back to stringification for XCom (#55880)
Even when stringify=false, we still need to make sure we have something
serializable to return in the API response. If the XCom value can't
work, we should still stringify it so the API can return something.
This was what API v1 did in Airflow 2.x.
---
.../airflow/api_fastapi/core_api/datamodels/xcom.py | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
index 0f22cd72262..174bfbadf30 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py
@@ -38,11 +38,31 @@ class XComResponse(BaseModel):
task_display_name: str = Field(validation_alias=AliasPath("task",
"task_display_name"))
+def _stringify_if_needed(value):
+ """
+ Check whether value is JSON-encodable (recursively if needed); stringify
it if not.
+
+ The list of JSON-ecodable types are taken from Python documentation:
+ https://docs.python.org/3/library/json.html#json.JSONEncoder
+ """
+ if value is None or isinstance(value, (str, int, float, bool)):
+ return value
+ if isinstance(value, dict):
+ return {str(k): _stringify_if_needed(v) for k, v in value.items()}
+ if isinstance(value, (list, tuple)):
+ return [_stringify_if_needed(v) for v in value]
+ return str(value)
+
+
class XComResponseNative(XComResponse):
"""XCom response serializer with native return type."""
value: Any
+ @field_validator("value", mode="before")
+ def value_to_json_serializable(cls, v):
+ return _stringify_if_needed(v)
+
class XComResponseString(XComResponse):
"""XCom response serializer with string return type."""