From 659aaafefc361d739f74db46818b3bb72692145e Mon Sep 17 00:00:00 2001 From: "David S. Batista" Date: Mon, 6 Jul 2026 18:07:05 +0200 Subject: [PATCH 1/3] adding try/catch to import_class_by_name to show incorreted imported class --- haystack/utils/base_serialization.py | 5 ++++- test/utils/test_base_serialization.py | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/haystack/utils/base_serialization.py b/haystack/utils/base_serialization.py index fe1929e1cd5..81b31de5c97 100644 --- a/haystack/utils/base_serialization.py +++ b/haystack/utils/base_serialization.py @@ -269,7 +269,10 @@ def _deserialize_value(value: dict[str, Any]) -> Any: payload = value["data"] # Custom class where value_type is a qualified class name - cls = import_class_by_name(value_type) + try: + cls = import_class_by_name(value_type) + except ImportError as e: + raise DeserializationError(f"Class '{value_type}' not correctly imported") from e # try from_dict (e.g. Haystack dataclasses and Components) if hasattr(cls, "from_dict") and callable(cls.from_dict): diff --git a/test/utils/test_base_serialization.py b/test/utils/test_base_serialization.py index e6cbbb99fc8..da5720409ba 100644 --- a/test/utils/test_base_serialization.py +++ b/test/utils/test_base_serialization.py @@ -423,6 +423,15 @@ def test_deserialize_value_with_wrong_value(): ) +def test_deserialize_value_with_schema_class_not_importable(): + with pytest.raises( + DeserializationError, match="Class 'test_base_serialization.NonExistentClass' not correctly imported" + ): + _deserialize_value_with_schema( + {"serialization_schema": {"type": "test_base_serialization.NonExistentClass"}, "serialized_data": {}} + ) + + def test_serialize_and_deserialize_pydantic_model(): model_instance = CustomModel(id=1, name="Test") serialized = _serialize_value_with_schema(model_instance) From 0a5beb7d4419a5774a6aba92f3e40976bdff470d Mon Sep 17 00:00:00 2001 From: "David S. Batista" Date: Mon, 6 Jul 2026 18:14:02 +0200 Subject: [PATCH 2/3] adding release notes --- .../notes/fix-deseri-import-class-5d22bc73b2089ecb.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 releasenotes/notes/fix-deseri-import-class-5d22bc73b2089ecb.yaml diff --git a/releasenotes/notes/fix-deseri-import-class-5d22bc73b2089ecb.yaml b/releasenotes/notes/fix-deseri-import-class-5d22bc73b2089ecb.yaml new file mode 100644 index 00000000000..7f578563ad8 --- /dev/null +++ b/releasenotes/notes/fix-deseri-import-class-5d22bc73b2089ecb.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed ``_deserialize_value_with_schema`` raising ``ImportError`` instead of ``DeserializationError`` + when a snapshot references a class that can no longer be imported. From 1f241722476458f287656a721acefc1d8a088a62 Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Mon, 6 Jul 2026 18:41:43 +0200 Subject: [PATCH 3/3] fix: also raise DeserializationError for class names without a module prefix import_class_by_name raises ValueError (not ImportError) when the type name has no dot to split on, so a corrupted snapshot with a dotless type name would still escape as a raw ValueError. Co-Authored-By: Claude Fable 5 --- haystack/utils/base_serialization.py | 3 ++- test/utils/test_base_serialization.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/haystack/utils/base_serialization.py b/haystack/utils/base_serialization.py index 81b31de5c97..83b35689e28 100644 --- a/haystack/utils/base_serialization.py +++ b/haystack/utils/base_serialization.py @@ -269,9 +269,10 @@ def _deserialize_value(value: dict[str, Any]) -> Any: payload = value["data"] # Custom class where value_type is a qualified class name + # ValueError covers type names without a module prefix, which import_class_by_name cannot split try: cls = import_class_by_name(value_type) - except ImportError as e: + except (ImportError, ValueError) as e: raise DeserializationError(f"Class '{value_type}' not correctly imported") from e # try from_dict (e.g. Haystack dataclasses and Components) diff --git a/test/utils/test_base_serialization.py b/test/utils/test_base_serialization.py index da5720409ba..ffb9fac7abf 100644 --- a/test/utils/test_base_serialization.py +++ b/test/utils/test_base_serialization.py @@ -432,6 +432,11 @@ def test_deserialize_value_with_schema_class_not_importable(): ) +def test_deserialize_value_with_schema_class_name_without_module(): + with pytest.raises(DeserializationError, match="Class 'NonExistentClass' not correctly imported"): + _deserialize_value_with_schema({"serialization_schema": {"type": "NonExistentClass"}, "serialized_data": {}}) + + def test_serialize_and_deserialize_pydantic_model(): model_instance = CustomModel(id=1, name="Test") serialized = _serialize_value_with_schema(model_instance)