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

amoghrajesh 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 b3cc48d5ab2 Make serde errors for unsupported types a bit more 
actionable (#70974)
b3cc48d5ab2 is described below

commit b3cc48d5ab232607fac6d434d2a36f6e5482deb8
Author: Amogh Desai <[email protected]>
AuthorDate: Mon Aug 3 17:36:36 2026 +0530

    Make serde errors for unsupported types a bit more actionable (#70974)
---
 task-sdk/src/airflow/sdk/serde/__init__.py  | 13 +++++++++++--
 task-sdk/tests/task_sdk/serde/test_serde.py | 18 ++++++++++++++----
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/task-sdk/src/airflow/sdk/serde/__init__.py 
b/task-sdk/src/airflow/sdk/serde/__init__.py
index 0d94ebc3282..f671545d3aa 100644
--- a/task-sdk/src/airflow/sdk/serde/__init__.py
+++ b/task-sdk/src/airflow/sdk/serde/__init__.py
@@ -285,7 +285,12 @@ def serialize(o: object, depth: int = 0) -> U | None:
         dct[DATA] = serialize(data, depth + 1)
         return dct
 
-    raise TypeError(f"cannot serialize object of type {cls}")
+    raise TypeError(
+        f"Cannot serialize object of type {cls}. Give it a `serialize()` 
method and a "
+        "`deserialize(data, version)` staticmethod, or decorate the class with 
@dataclass or "
+        "@attr.define. "
+        "See: 
https://airflow.apache.org/docs/apache-airflow/stable/authoring-and-scheduling/serializers.html";
+    )
 
 
 def deserialize(o: T | None, full=True, type_hint: Any = None) -> object:
@@ -387,7 +392,11 @@ def deserialize(o: T | None, full=True, type_hint: Any = 
None) -> object:
         return cls(**deserialize_value)  # type: ignore[operator]
 
     # no deserializer available
-    raise TypeError(f"No deserializer found for {classname}")
+    raise TypeError(
+        f"No deserializer found for {classname}. It must provide a 
`deserialize(data, version)` "
+        "staticmethod (matching how it serializes), or be decorated with 
@dataclass or @attr.define. "
+        "See: 
https://airflow.apache.org/docs/apache-airflow/stable/authoring-and-scheduling/serializers.html";
+    )
 
 
 def _convert(old: dict) -> dict:
diff --git a/task-sdk/tests/task_sdk/serde/test_serde.py 
b/task-sdk/tests/task_sdk/serde/test_serde.py
index 16d6851b40b..37d93a6e895 100644
--- a/task-sdk/tests/task_sdk/serde/test_serde.py
+++ b/task-sdk/tests/task_sdk/serde/test_serde.py
@@ -297,7 +297,7 @@ class TestSerDe:
 
     def test_no_serializer(self):
         i = Exception
-        with pytest.raises(TypeError, match="^cannot serialize"):
+        with pytest.raises(TypeError, match="^Cannot serialize"):
             serialize(i)
 
     def test_ser_registered(self):
@@ -523,8 +523,13 @@ class TestSerDe:
                 "__version__": 0,
             }
         )
-        with pytest.raises(TypeError, match="No deserializer"):
+        with pytest.raises(TypeError, match="No deserializer") as exc_info:
             deserialize(data)
+        assert (
+            "It must provide a `deserialize(data, version)` staticmethod 
(matching how it "
+            "serializes), or be decorated with @dataclass or @attr.define." in 
str(exc_info.value)
+        )
+        assert "authoring-and-scheduling/serializers.html" in 
str(exc_info.value)
 
     def test_backwards_compat(self):
         """
@@ -645,6 +650,11 @@ class TestSerDe:
         i = C()
         with pytest.raises(
             TypeError,
-            match="cannot serialize object of type <class 
'tests.task_sdk.serde.test_serde.C'>",
-        ):
+            match="Cannot serialize object of type <class 
'tests.task_sdk.serde.test_serde.C'>",
+        ) as exc_info:
             serialize(i)
+        assert (
+            "Give it a `serialize()` method and a `deserialize(data, version)` 
staticmethod, or "
+            "decorate the class with @dataclass or @attr.define." in 
str(exc_info.value)
+        )
+        assert "authoring-and-scheduling/serializers.html" in 
str(exc_info.value)

Reply via email to