deepset-ai/haystack · error · DeserializationError
{e}
Error message
{e} What it means
When a type string contains a dot, deserialize_type() tries to import it with _import_class_by_name(); an ImportError there is re-raised as DeserializationError(str(e)) with this message. It means the module or class path stored in the serialized data could not be imported. This guards against loading pipelines that reference unavailable or blocked code.
Source
Thrown at haystack/utils/type_serialization.py:269
# arguments.
if main_type is typing.Literal:
return typing.Literal[ast.literal_eval(f"({generics_str},)")]
generic_args = [_deserialize_type_arg(arg) for arg in _parse_generic_args(generics_str)]
# Reconstruct
try:
return main_type[tuple(generic_args) if len(generic_args) > 1 else generic_args[0]]
except (TypeError, AttributeError) as e:
raise DeserializationError(f"Could not apply arguments {generic_args} to type {main_type}") from e
# Handle non-generic types
# First, check if there's a module prefix
if "." in type_str:
try:
return _import_class_by_name(type_str)
except ImportError as e:
raise DeserializationError(str(e)) from e
# No module prefix, check builtins and typing.
# (None / NoneType / Ellipsis are handled at the top of this function, before they can reach the
# builtin type gate below which would refuse them for not being types.)
if hasattr(builtins, type_str):
resolved = getattr(builtins, type_str)
# This bare-name path never consults the allowlist. A type annotation must resolve to an
# actual type, so builtin functions like `eval`/`exec` are rejected while types pass.
_check_builtin_is_type(resolved, type_str)
return resolved
# Then check typing
if hasattr(typing, type_str):
return getattr(typing, type_str)
raise DeserializationError(f"Could not deserialize type: {type_str}")
View on GitHub (pinned to e318778c9b)
Solutions
- Install or fix the import path for the module referenced in the type string (pip install the package)
- Check for renames: update the serialized type string to the current module/class path
- If the class is intentionally blocked (haystack internal), use the public replacement type
- Reproduce with `from my.module import MyClass` to see the real import error
Example fix
// before
{"type": "haystack.testing.factory.TestComponent"}
// after
{"type": "my_app.components.TestComponent"} # valid importable path Defensive patterns
Strategy: try-catch
Validate before calling
import importlib
def can_import(dotted):
mod, _, attr = dotted.rpartition(".")
try:
return hasattr(importlib.import_module(mod), attr)
except ImportError:
return False Try / catch
from haystack.utils import DeserializationError
try:
t = deserialize_type(type_str)
except DeserializationError as e:
# str(e) is the underlying ImportError message
raise RuntimeError(f"Cannot load pipeline, missing component: {e}") from e Prevention
- Pin and install all component dependencies in the target environment
- Use fully qualified, stable public class paths in serialized data
- Re-serialize pipelines after upgrading haystack versions
When it happens
Trigger: deserialize_type('my.module.MyClass') where my.module is not installed, renamed, or the class attribute no longer exists; loading a pipeline YAML created in another project/environment.
Common situations: Missing optional dependency in the target environment; package refactor renamed module paths between versions; pickled/serialized component schema shared across codebases.
Related errors
- Could not import '{fully_qualified_name}'
- Could not import '{type_str}' as it may not exist or is not
- Refusing to deserialize an OutputAdapter with unsafe=True wh
- Refusing to deserialize an OutputAdapter with custom filters
- Missing 'type' in serialization data
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/40505bb6b0d7e049.
Report an issue: GitHub.