{"record":{"id":"4dab95fb68d699af","repo":"deepset-ai/haystack","slug":"adding-a-toolset-to-another-toolset-is-deprecated","errorCode":null,"errorMessage":"Adding a Toolset to another Toolset is deprecated and will be removed in Haystack 3.2.0. Pass Toolsets as a list wherever tools are accepted instead, e.g. Agent(tools=[toolset_a, toolset_b]).","messagePattern":"Adding a Toolset to another Toolset is deprecated and will be removed in Haystack 3\\.2\\.0\\. Pass Toolsets as a list wherever tools are accepted instead, e\\.g\\. Agent\\(tools=\\[toolset_a, toolset_b\\]\\)\\.","errorType":"console","errorClass":"FutureWarning","httpStatus":null,"severity":"warning","filePath":"haystack/tools/toolset.py","lineNumber":213,"sourceCode":"\n        Note: adding a Toolset flattens it into its individual tools, so this is only recommended\n        for Toolsets that don't manage shared resources in their `warm_up()` (or `__init__`).\n        For example, combining with an `MCPToolset`, which owns a shared connection, is not\n        recommended: the connection's lifecycle would no longer be managed by the original\n        Toolset.\n\n        Adding a Toolset is deprecated and will be removed in Haystack 3.2.0: pass Toolsets as a\n        list wherever tools are accepted instead, e.g. `Agent(tools=[toolset_a, toolset_b])`.\n\n        :param tool: A Tool instance or another Toolset to add\n        :raises ValueError: If adding the tool would result in duplicate tool names\n        :raises TypeError: If the provided object is not a Tool or Toolset\n        \"\"\"\n        if not isinstance(tool, (Tool, Toolset)):\n            raise TypeError(f\"Expected Tool or Toolset, got {type(tool).__name__}\")\n\n        if isinstance(tool, Toolset):\n            warnings.warn(\n                \"Adding a Toolset to another Toolset is deprecated and will be removed in Haystack 3.2.0. \"\n                \"Pass Toolsets as a list wherever tools are accepted instead, \"\n                \"e.g. Agent(tools=[toolset_a, toolset_b]).\",\n                FutureWarning,\n                stacklevel=2,\n            )\n\n        new_tools = [tool] if isinstance(tool, Tool) else list(tool)\n\n        # Check for duplicates before adding\n        _check_duplicate_tool_names(self.tools + new_tools)\n        self.tools.extend(new_tools)\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"\n        Serialize the Toolset to a dictionary.\n\n        :returns: A dictionary representation of the Toolset","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/tools/toolset.py#L195-L231","documentation":"Toolset.add(tool) in haystack/tools/toolset.py emits this FutureWarning when the object being added is itself a Toolset. Nesting one Toolset inside another via add() is deprecated in favor of passing toolsets as a flat list to any API that accepts tools (removed in Haystack 3.2.0).","triggerScenarios":"Calling toolset_a.add(toolset_b) where toolset_b is an instance of Toolset (or subclass); the TypeError check passes because Toolset is an allowed type, then the warning fires.","commonSituations":"Building a combined tool catalog by incrementally adding toolsets into a master Toolset; refactors where a variable that used to be a Tool became a Toolset; utility functions typed to accept Tool that now receive Toolset instances.","solutions":["Stop calling .add() with a Toolset; pass toolsets directly as a list where tools are accepted, e.g. Agent(tools=[toolset_a, toolset_b])","If a single flat collection is required, iterate and add individual Tools: for t in toolset_b: toolset_a.add(t)","Combine with list concatenation of Toolsets: Toolset(toolsets=[toolset_a, toolset_b]) or use a plain list [toolset_a, toolset_b]","Suppress with warnings.filterwarnings('ignore', category=FutureWarning, module='haystack') only as a temporary measure before Haystack 3.2.0"],"exampleFix":"# before\ncatalog = Toolset(tools=[])\ncatalog.add(toolset_a)\ncatalog.add(toolset_b)\nagent = Agent(chat_generator=gen, tools=[catalog])\n# after\nagent = Agent(chat_generator=gen, tools=[toolset_a, toolset_b])\n# or, if a flat Toolset is required:\nfor t in toolset_a:\n    catalog.add(t)\nfor t in toolset_b:\n    catalog.add(t)","handlingStrategy":"type-guard","validationCode":"from haystack.tools import Tool, Toolset\n\ndef safe_add(target: Toolset, item) -> None:\n    if isinstance(item, Toolset):\n        raise ValueError(\"Pass toolsets as a list to consumers, not via .add()\")\n    if not isinstance(item, Tool):\n        raise TypeError(f\"Expected Tool, got {type(item).__name__}\")\n    target.add(item)","typeGuard":"from haystack.tools import Tool, Toolset\n\ndef is_tool(item) -> bool:\n    return isinstance(item, Tool) and not isinstance(item, Toolset)\n\ndef is_toolset(item) -> bool:\n    return isinstance(item, Toolset)","tryCatchPattern":"import warnings\nfrom haystack.tools import Toolset\n\nwith warnings.catch_warnings(record=True) as caught:\n    warnings.simplefilter(\"always\", FutureWarning)\n    target.add(maybe_toolset)\n    if any(issubclass(w.category, FutureWarning) for w in caught):\n        # a Toolset was passed; refactor to pass it as a list instead\n        pass","preventionTips":["Type helper functions as Tool | Toolset and branch on isinstance before calling .add()","Never call toolset.add(other_toolset); keep toolsets separate in lists","Search codebases for '.add(' on Toolset variables during Haystack upgrades","Migrate to Agent(tools=[toolset_a, toolset_b]) style before Haystack 3.2.0"],"tags":["deprecation","toolset","python"],"backgroundTag":"toolset-nesting-deprecated","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}