deepset-ai/haystack · error · SerializationError
Serialization of nested functions is not supported.
Error message
Serialization of nested functions is not supported.
What it means
serialize_callable raises SerializationError when __qualname__ contains '<locals>', meaning the callable is a nested function defined inside another function. Such a function cannot be imported by path and therefore cannot be deserialized, so serialization is refused.
Source
Thrown at haystack/utils/callable_serialization.py:47
Serializes a callable to its full path.
:param callable_handle: The callable to serialize
:return: The full path of the callable
"""
try:
full_arg_spec = inspect.getfullargspec(callable_handle)
is_instance_method = bool(full_arg_spec.args and full_arg_spec.args[0] == "self")
except TypeError:
is_instance_method = False
if is_instance_method:
raise SerializationError("Serialization of instance methods is not supported.")
# __qualname__ contains the fully qualified path we need for classmethods and staticmethods
qualname = getattr(callable_handle, "__qualname__", "")
if "<lambda>" in qualname:
raise SerializationError("Serialization of lambdas is not supported.")
if "<locals>" in qualname:
raise SerializationError("Serialization of nested functions is not supported.")
name = qualname or callable_handle.__name__
# Get the full package path of the function
module = inspect.getmodule(callable_handle)
if module is not None:
full_path = f"{module.__name__}.{name}"
else:
full_path = name
# Serialization succeeds, but a denied builtin (e.g. `eval`) won't reload without `unsafe=True`.
if _is_denied_builtin(callable_handle):
logger.warning(
"Serialized callable '{full_path}' is a builtin that is blocked during deserialization; "
"the resulting pipeline will only be loadable with unsafe=True.",
full_path=full_path,
)
View on GitHub (pinned to e318778c9b)
Solutions
- Move the function to module level so it has an importable path
- Return a module-level function from the factory instead of defining it inline
- Promote the logic to a small callable class defined at module level
Example fix
// before
def build():
def splitter(t): return t.split()
return TextSplitter(splitting_function=splitter)
// after
# module level
def splitter(t): return t.split()
def build():
return TextSplitter(splitting_function=splitter) Defensive patterns
Strategy: validation
Validate before calling
def is_nested(fn) -> bool:
return "<locals>" in getattr(fn, "__qualname__", "") Type guard
import types
def is_module_level(fn) -> bool:
return isinstance(fn, types.FunctionType) and "<locals>" not in fn.__qualname__ Try / catch
try:
serialized = pipeline.dumps()
except SerializationError as e:
logger.error("nested function passed as callable: %s", e)
raise Prevention
- Define callbacks at module top level, never inside functions
- Move notebook-defined callbacks into a helper module
- Keep factory functions returning module-level function references
When it happens
Trigger: Defining a callback inside a function (e.g. def main(): def splitter(t): ...; TextSplitter(splitting_function=splitter)) then calling to_dict on the component or pipeline.
Common situations: Callbacks defined in notebooks, test fixtures, or CLI entry points; factory functions that build pipelines with locally-defined callbacks.
Related errors
- Serialization of instance methods is not supported.
- Serialization of lambdas is not supported.
- Component '{name}' of type '{type(component).__name__}' has
- Component '{name}' of type '{type(component).__name__}' has
- Component '{name}' of type '{type(component).__name__}' has
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/aba47da77bafd563.
Report an issue: GitHub.