{"record":{"id":"8af3ac2cc67194b9","repo":"microsoft/autogen","slug":"handoff-names-must-be-unique-handoff-tool-names","errorCode":null,"errorMessage":"Handoff names must be unique: {handoff_tool_names}","messagePattern":"Handoff names must be unique: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py","lineNumber":808,"sourceCode":"\n        # Handoff tools.\n        self._handoff_tools: List[BaseTool[Any, Any]] = []\n        self._handoffs: Dict[str, HandoffBase] = {}\n        if handoffs is not None:\n            if model_client.model_info[\"function_calling\"] is False:\n                raise ValueError(\"The model does not support function calling, which is needed for handoffs.\")\n            for handoff in handoffs:\n                if isinstance(handoff, str):\n                    handoff = HandoffBase(target=handoff)\n                if isinstance(handoff, HandoffBase):\n                    self._handoff_tools.append(handoff.handoff_tool)\n                    self._handoffs[handoff.name] = handoff\n                else:\n                    raise ValueError(f\"Unsupported handoff type: {type(handoff)}\")\n        # Check if handoff tool names are unique.\n        handoff_tool_names = [tool.name for tool in self._handoff_tools]\n        if len(handoff_tool_names) != len(set(handoff_tool_names)):\n            raise ValueError(f\"Handoff names must be unique: {handoff_tool_names}\")\n        # Create sets for faster lookup\n        tool_names_set = set(tool_names)\n        handoff_tool_names_set = set(handoff_tool_names)\n\n        # Check if there's any overlap between handoff tool names and tool names\n        overlap = tool_names_set.intersection(handoff_tool_names_set)\n\n        # Also check if any handoff target name matches a tool name\n        # This handles the case where a handoff is specified directly with a string that matches a tool name\n        for handoff in handoffs or []:\n            if isinstance(handoff, str) and handoff in tool_names_set:\n                raise ValueError(\"Handoff names must be unique from tool names\")\n            elif isinstance(handoff, HandoffBase) and handoff.target in tool_names_set:\n                raise ValueError(\"Handoff names must be unique from tool names\")\n\n        if overlap:\n            raise ValueError(\"Handoff names must be unique from tool names\")\n","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py#L790-L826","documentation":"AssistantAgent checks that handoff tool names are unique among themselves; duplicates (e.g. two handoffs to the same target, which produce identically named handoff tools) raise ValueError listing all handoff tool names.","triggerScenarios":"Passing handoffs=[\"agent_b\", \"agent_b\"], or two HandoffBase instances whose handoff tools share a name (commonly the same target specified twice, since the tool name is derived from the target).","commonSituations":"Programmatically generating handoff lists and accidentally including a target twice, or refactoring team definitions that merge handoff lists with overlapping targets.","solutions":["Remove duplicate handoff entries; each target agent should appear once.","If two distinct handoffs to the same target are needed, give them distinct names via HandoffBase subclassing so the generated tools differ.","De-duplicate string lists before passing: handoffs=list(dict.fromkeys(handoffs))."],"exampleFix":"# before\nagent = AssistantAgent(name=\"a\", model_client=client, handoffs=[\"b\", \"b\"])\n\n# after\nagent = AssistantAgent(name=\"a\", model_client=client, handoffs=[\"b\"])","handlingStrategy":"validation","validationCode":"handoffs = list(dict.fromkeys(handoffs)) if all(isinstance(h, str) for h in handoffs) else handoffs\nnames = [h.target for h in handoffs]\nassert len(names) == len(set(names)), f\"duplicate handoff targets: {names}\"","typeGuard":"def has_unique_handoff_targets(handoffs) -> bool:\n    targets = [h if isinstance(h, str) else h.target for h in handoffs or []]\n    return len(targets) == len(set(targets))","tryCatchPattern":"try:\n    agent = AssistantAgent(name=\"a\", model_client=client, handoffs=handoffs)\nexcept ValueError as e:\n    if \"Handoff names must be unique\" in str(e) and all(isinstance(h, str) for h in handoffs):\n        agent = AssistantAgent(name=\"a\", model_client=client, handoffs=list(dict.fromkeys(handoffs)))\n    else:\n        raise","preventionTips":["Deduplicate string handoff targets before constructing the agent.","When merging handoff lists from multiple modules, union by target name."],"tags":["python","handoffs","uniqueness","autogen"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}