microsoft/autogen · error · ValueError

Unsupported handoff type: {type(handoff)}

Error message

Unsupported handoff type: {type(handoff)}

What it means

While processing the handoffs argument, AssistantAgent accepts only strings (converted to HandoffBase with that target) or HandoffBase instances; each entry that is neither raises ValueError with its type. This runs after the function-calling check, inside the per-handoff loop.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:804

        # Check if tool names are unique.
        tool_names = [tool.name for tool in self._tools]
        if len(tool_names) != len(set(tool_names)):
            raise ValueError(f"Tool names must be unique: {tool_names}")

        # Handoff tools.
        self._handoff_tools: List[BaseTool[Any, Any]] = []
        self._handoffs: Dict[str, HandoffBase] = {}
        if handoffs is not None:
            if model_client.model_info["function_calling"] is False:
                raise ValueError("The model does not support function calling, which is needed for handoffs.")
            for handoff in handoffs:
                if isinstance(handoff, str):
                    handoff = HandoffBase(target=handoff)
                if isinstance(handoff, HandoffBase):
                    self._handoff_tools.append(handoff.handoff_tool)
                    self._handoffs[handoff.name] = handoff
                else:
                    raise ValueError(f"Unsupported handoff type: {type(handoff)}")
        # Check if handoff tool names are unique.
        handoff_tool_names = [tool.name for tool in self._handoff_tools]
        if len(handoff_tool_names) != len(set(handoff_tool_names)):
            raise ValueError(f"Handoff names must be unique: {handoff_tool_names}")
        # Create sets for faster lookup
        tool_names_set = set(tool_names)
        handoff_tool_names_set = set(handoff_tool_names)

        # Check if there's any overlap between handoff tool names and tool names
        overlap = tool_names_set.intersection(handoff_tool_names_set)

        # Also check if any handoff target name matches a tool name
        # This handles the case where a handoff is specified directly with a string that matches a tool name
        for handoff in handoffs or []:
            if isinstance(handoff, str) and handoff in tool_names_set:
                raise ValueError("Handoff names must be unique from tool names")
            elif isinstance(handoff, HandoffBase) and handoff.target in tool_names_set:
                raise ValueError("Handoff names must be unique from tool names")

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Use plain strings (target agent names) or HandoffBase/its subclasses for handoffs entries.
  2. Ensure only one consistent autogen-agentchat/autogen-core version is installed (`pip list | grep autogen`).
  3. Wrap custom handoff logic in a HandoffBase subclass with a message and target.

Example fix

# before
agent = AssistantAgent(name="a", model_client=client, handoffs=[{"target": "researcher"}])

# after
agent = AssistantAgent(name="a", model_client=client, handoffs=[HandoffBase(target="researcher", message="Task passed to researcher.")])
Defensive patterns

Strategy: type-guard

Validate before calling

from autogen_agentchat.agents._assistant_agent import HandoffBase
for h in handoffs or []:
    if not isinstance(h, (str, HandoffBase)):
        raise ValueError(f"Unsupported handoff entry: {h!r} ({type(h).__name__})")

Type guard

def is_valid_handoff(h) -> bool:
    return isinstance(h, str) or isinstance(h, HandoffBase)

Try / catch

try:
    agent = AssistantAgent(name="a", model_client=client, handoffs=handoffs)
except ValueError as e:
    if "Unsupported handoff type" in str(e):
        handoffs = [h if isinstance(h, (str, HandoffBase)) else HandoffBase(target=str(h)) for h in handoffs]
    else:
        raise

Prevention

When it happens

Trigger: Passing handoffs=[123], handoffs=[{"target": "b"}], a Tool instance, or any custom handoff class that does not subclass HandoffBase (or subclasses one from a mismatched autogen install).

Common situations: Using dict-style handoff specs from tutorials of other frameworks, duplicate autogen package copies breaking isinstance, or passing a HandoffBase subclass instance from an older API version.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/1734f2cf1d274628. Report an issue: GitHub.