deepset-ai/haystack · error · DeserializationError
Class '{data['type']}' can't be deserialized as '{cls.__name
Error message
Class '{data['type']}' can't be deserialized as '{cls.__name__}' What it means
The serialized 'type' field must exactly match the fully-qualified name of the class being deserialized. default_from_dict() raises this when the data's 'type' points to a different class than the one from_dict() was called on, preventing construction of the wrong object from mislabeled data.
Source
Thrown at haystack/core/serialization.py:301
:param cls:
The class to be used for deserialization.
:param data:
The serialized data.
:returns:
The deserialized object.
:raises DeserializationError:
If the `type` field in `data` is missing or it doesn't match the type of `cls`.
"""
# Copy so that replacing serialized sub-objects (Secret/ComponentDevice/nested components) with their
# deserialized instances below does not mutate the caller's ``data`` dict in place. Without this, a second
# deserialization of the same dict would receive already-parsed objects instead of their serialized form.
init_params = dict(data.get("init_parameters", {}))
if "type" not in data:
raise DeserializationError("Missing 'type' in serialization data")
if data["type"] != generate_qualified_class_name(cls):
raise DeserializationError(f"Class '{data['type']}' can't be deserialized as '{cls.__name__}'")
valid_init_param_names = _init_parameter_names(cls)
# Automatically detect and deserialize objects with from_dict methods
for key, value in init_params.items():
if isinstance(value, dict) and "type" in value:
type_value = value.get("type")
# Special handling for Secret (type == "env_var")
if type_value == "env_var":
init_params[key] = Secret.from_dict(value)
# Special handling for ComponentDevice (type == "single" or "multiple")
elif _is_serialized_component_device(value):
init_params[key] = ComponentDevice.from_dict(value)
# If type looks like a fully qualified class name, try to import it and deserialize
elif isinstance(type_value, str) and "." in type_value:
# Reject before importing if the parent class does not accept this parameter.
# This blocks YAML that smuggles untrusted classes into unused parameter slots.
if valid_init_param_names is not None and key not in valid_init_param_names:View on GitHub (pinned to e318778c9b)
Solutions
- Update data['type'] to the current fully-qualified class name.
- Re-export the pipeline from an environment with the original component installed.
- Check the haystack version and migrate serialized configs to the new class paths.
- Ensure from_dict is called on the correct class rather than a sibling class.
Example fix
// before
{"type": "haystack.nodes.retriever.sparse.ElasticsearchRetriever", ...}
// after
{"type": "haystack.components.retrievers.in_memory.InMemoryBM25Retriever", ...} Defensive patterns
Strategy: validation
Validate before calling
from haystack.core.serialization import generate_qualified_class_name
assert data.get("type") == generate_qualified_class_name(MyComponent), data.get("type") Type guard
def matches_class(data: dict, cls) -> bool:
from haystack.core.serialization import generate_qualified_class_name
return isinstance(data, dict) and data.get("type") == generate_qualified_class_name(cls) Try / catch
from haystack.core.errors import DeserializationError
try:
comp = MyComponent.from_dict(data)
except DeserializationError as e:
if "can't be deserialized as" in str(e):
data["type"] = generate_qualified_class_name(MyComponent)
comp = MyComponent.from_dict(data) Prevention
- Update serialized 'type' strings after class renames/moves
- Pin haystack versions between pipeline export and load
- Re-export pipelines rather than hand-editing type fields
When it happens
Trigger: Calling SomeComponent.from_dict(data) where data['type'] is a different class (e.g. renamed or moved class, copy-pasted serialized block, or loading a component dict into the wrong class).
Common situations: Class renamed/moved between haystack versions so old serialized pipelines carry the old qualified name; hand-copied YAML with a stale type string; custom component refactors changing module paths.
Related errors
- Refusing to deserialize an OutputAdapter with unsafe=True wh
- Refusing to deserialize an OutputAdapter with custom filters
- Couldn't deserialize component '{name}' of class '{component
- Missing 'type' in serialization data
- Refusing to deserialize unknown parameter '{key}' for '{cls.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/74f37798406b5683.
Report an issue: GitHub.