{"record":{"id":"bb106b59b850e52d","repo":"deepset-ai/haystack","slug":"invalid-item-type-type-item-must-be-tool-or-s","errorCode":null,"errorMessage":"Invalid item type: {type(item)}. Must be Tool or str.","messagePattern":"Invalid item type: (.+?)\\. Must be Tool or str\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"haystack/tools/searchable_toolset.py","lineNumber":334,"sourceCode":"        if self._passthrough:\n            yield from (tool for tool in self._catalog if self._is_selected(tool.name))\n        else:\n            if self._bootstrap_tool is not None:\n                yield self._bootstrap_tool\n            yield from (tool for tool in self._discovered_tools.values() if self._is_selected(tool.name))\n\n    def __contains__(self, item: str | Tool) -> bool:\n        \"\"\"\n        Check if a tool is available by Tool instance or tool name string.\n\n        :param item: Tool instance or tool name string.\n        :returns: True if the tool is available, False otherwise.\n        \"\"\"\n        if isinstance(item, str):\n            return any(tool.name == item for tool in self)\n        if isinstance(item, Tool):\n            return any(tool == item for tool in self)\n        raise TypeError(f\"Invalid item type: {type(item)}. Must be Tool or str.\")\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"\n        Serialize the toolset to a dictionary.\n\n        :returns: Dictionary representation of the toolset.\n        \"\"\"\n        data: dict[str, Any] = {\n            \"catalog\": serialize_tools_or_toolset(self._raw_catalog),\n            \"top_k\": self._top_k,\n            \"search_threshold\": self._search_threshold,\n            \"search_tool_name\": self._search_tool_name,\n            \"search_tool_description\": self._search_tool_description,\n            \"search_tool_parameters_description\": self._search_tool_parameters_description,\n        }\n\n        return {\"type\": generate_qualified_class_name(type(self)), \"data\": data}\n","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/tools/searchable_toolset.py#L316-L352","documentation":"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.","triggerScenarios":"x in searchable_toolset where x is a Toolset, dict, or other non-Tool/str object.","commonSituations":"Checking membership of a toolset inside another toolset; passing tool names wrapped in dicts like {'name': 'tool'}; sloppy checks before adding a tool.","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"],"exampleFix":"// before\nif {\"name\": \"search\"} in toolset: ...\n\n// after\nif \"search\" in toolset: ...","handlingStrategy":"type-guard","validationCode":"def safe_contains(toolset, item) -> bool:\n    from haystack.tools import Tool\n    if isinstance(item, (Tool, str)):\n        return item in toolset\n    if isinstance(item, dict) and isinstance(item.get(\"name\"), str):\n        return item[\"name\"] in toolset\n    raise TypeError(f\"Cannot check membership for {type(item)}\")","typeGuard":"def is_membership_key(item) -> bool:\n    from haystack.tools import Tool\n    return isinstance(item, (Tool, str))","tryCatchPattern":"try:\n    present = item in toolset\nexcept TypeError:\n    name = getattr(item, \"name\", None) or (item.get(\"name\") if isinstance(item, dict) else None)\n    present = isinstance(name, str) and name in toolset","preventionTips":["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"],"tags":["type-check","toolset","membership"],"backgroundTag":"wrong-argument-type","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}