deepset-ai/haystack · error · TypeError
Invalid item type: {type(item)}. Must be Tool or str.
Error message
Invalid item type: {type(item)}. Must be Tool or str. What it means
SearchableToolset.__contains__ (the 'in' operator) only accepts a Tool instance or a str tool name. Passing any other type (dict, Toolset, int, None) raises TypeError, since membership cannot be meaningfully checked.
Source
Thrown at haystack/tools/searchable_toolset.py:334
if self._passthrough:
yield from (tool for tool in self._catalog if self._is_selected(tool.name))
else:
if self._bootstrap_tool is not None:
yield self._bootstrap_tool
yield from (tool for tool in self._discovered_tools.values() if self._is_selected(tool.name))
def __contains__(self, item: str | Tool) -> bool:
"""
Check if a tool is available by Tool instance or tool name string.
:param item: Tool instance or tool name string.
:returns: True if the tool is available, False otherwise.
"""
if isinstance(item, str):
return any(tool.name == item for tool in self)
if isinstance(item, Tool):
return any(tool == item for tool in self)
raise TypeError(f"Invalid item type: {type(item)}. Must be Tool or str.")
def to_dict(self) -> dict[str, Any]:
"""
Serialize the toolset to a dictionary.
:returns: Dictionary representation of the toolset.
"""
data: dict[str, Any] = {
"catalog": serialize_tools_or_toolset(self._raw_catalog),
"top_k": self._top_k,
"search_threshold": self._search_threshold,
"search_tool_name": self._search_tool_name,
"search_tool_description": self._search_tool_description,
"search_tool_parameters_description": self._search_tool_parameters_description,
}
return {"type": generate_qualified_class_name(type(self)), "data": data}
View on GitHub (pinned to e318778c9b)
Solutions
- Check with a str name: 'tool_name' in toolset
- Or check with the Tool instance itself: my_tool in toolset
- If you have a dict, extract the name: item['name'] in toolset
Example fix
// before
if {"name": "search"} in toolset: ...
// after
if "search" in toolset: ... Defensive patterns
Strategy: type-guard
Validate before calling
def safe_contains(toolset, item) -> bool:
from haystack.tools import Tool
if isinstance(item, (Tool, str)):
return item in toolset
if isinstance(item, dict) and isinstance(item.get("name"), str):
return item["name"] in toolset
raise TypeError(f"Cannot check membership for {type(item)}") Type guard
def is_membership_key(item) -> bool:
from haystack.tools import Tool
return isinstance(item, (Tool, str)) Try / catch
try:
present = item in toolset
except TypeError:
name = getattr(item, "name", None) or (item.get("name") if isinstance(item, dict) else None)
present = isinstance(name, str) and name in toolset Prevention
- Always check membership by tool name (str) or Tool instance
- Normalize tool references to names at agent boundaries
- Never pass dicts or nested toolsets to 'in' checks
When it happens
Trigger: x in searchable_toolset where x is a Toolset, dict, or other non-Tool/str object.
Common situations: Checking membership of a toolset inside another toolset; passing tool names wrapped in dicts like {'name': 'tool'}; sloppy checks before adding a tool.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- Invalid catalog type: {type(catalog)}. Expected Tool, Toolse
- Items in the tools list must be Tool or Toolset instances.
- The 'pipeline' parameter must be an instance of Pipeline. Go
- Invalid search_tool_parameters_description keys: {invalid_ke
- SearchableToolset does not support concatenation.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/bb106b59b850e52d.
Report an issue: GitHub.