deepset-ai/haystack · error · TypeError
Items in the tools list must be Tool or Toolset instances.
Error message
Items in the tools list must be Tool or Toolset instances.
What it means
serialize_tools_or_toolset in haystack/tools/serde_utils.py serializes toolsets and tool lists for pipeline serialization (to_dict). When given a list, each item must be a Tool or Toolset and is serialized via its to_dict(); any other item raises TypeError. This guards pipeline save/loading against corrupted tool registries.
Source
Thrown at haystack/tools/serde_utils.py:33
def serialize_tools_or_toolset(tools: "ToolsType | None") -> dict[str, Any] | list[dict[str, Any]] | None:
"""
Serialize tools or toolsets to dictionaries.
:param tools: A Toolset, a list of Tools and/or Toolsets, or None
:returns: Serialized representation preserving Tool/Toolset boundaries when provided
"""
if tools is None:
return None
if isinstance(tools, Toolset):
return tools.to_dict()
if isinstance(tools, list):
serialized: list[dict[str, Any]] = []
for item in tools:
if isinstance(item, (Toolset, Tool)):
serialized.append(item.to_dict())
else:
raise TypeError("Items in the tools list must be Tool or Toolset instances.")
return serialized
raise TypeError("tools must be Toolset, list[Union[Tool, Toolset]], or None")
def deserialize_tools_or_toolset_inplace(data: dict[str, Any], key: str = "tools") -> None:
"""
Deserialize a list of Tools and/or Toolsets, or a single Toolset in a dictionary inplace.
:param data:
The dictionary with the serialized data.
:param key:
The key in the dictionary where the list of Tools and/or Toolsets, or single Toolset is stored.
"""
if key in data:
serialized_tools = data[key]
if serialized_tools is None:
returnView on GitHub (pinned to e318778c9b)
Solutions
- Ensure every element of the tools list is an instantiated Tool or Toolset before serializing
- Replace raw dict representations with proper Tool.from_dict(...) / Toolset instances
- Filter out None or placeholder entries before to_dict()
- If you have a single Tool, confirm you're using the intended Toolset/Tool to_dict path
Example fix
// before toolset.to_dict() # tools contains raw dicts // after tools = [Tool.from_dict(d) if isinstance(d, dict) else d for d in raw_tools] ts = Toolset(tools=tools) ts.to_dict()
Defensive patterns
Strategy: validation
Validate before calling
from haystack.tools import Tool, Toolset
def validate_serializable_tools(tools) -> None:
if tools is None or isinstance(tools, Toolset):
return
for i, item in enumerate(tools):
if not isinstance(item, (Tool, Toolset)):
raise TypeError(f"tools[{i}] is {type(item).__name__}; must be Tool or Toolset before to_dict()") Type guard
def is_serializable_tools_list(tools) -> bool:
from haystack.tools import Tool, Toolset
return tools is None or isinstance(tools, Toolset) or (
isinstance(tools, list) and all(isinstance(i, (Tool, Toolset)) for i in tools)
) Try / catch
try:
data = toolset.to_dict()
except TypeError as e:
logger.error("Tool registry corrupted for serialization: %s", e)
raise Prevention
- Only insert instantiated Tool/Toolset objects into tools lists
- Rehydrate raw dicts with Tool.from_dict before registering
- Validate the tools list before any pipeline to_dict()/dump operation
When it happens
Trigger: Calling to_dict() on a Toolset/serializable component whose tools list contains non-Tool/non-Toolset items (dicts, raw callables, None, partially constructed objects).
Common situations: Manually building a tools list and inserting raw dicts or un-instantiated factories; deserialization bugs that left placeholders in the list; passing a single Tool (not in a list) with the list-handling path expected.
Related errors
- Invalid catalog type: {type(catalog)}. Expected Tool, Toolse
- Invalid item type: {type(item)}. Must be Tool or str.
- Missing 'type' in component '{name}'
- Successfully imported module '{module}' but couldn't find '{
- Component '{component_type}' (name: '{name}') not imported.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/1184005177bad2d8.
Report an issue: GitHub.