microsoft/autogen · error · RuntimeError

Handoff message target does not match agent name: {messages[

Error message

Handoff message target does not match agent name: {messages[-1].source}

What it means

UserProxyAgent._get_latest_handoff() accepts the last message only if it is a HandoffMessage whose target equals this agent's name; otherwise it raises. Note the message text prints the message's source, but the actual failed comparison is target vs. the agent's name. This guard keeps handoff routing consistent when on_messages is invoked directly.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_user_proxy_agent.py:183

        input_func: Optional[InputFuncType] = None,
    ) -> None:
        """Initialize the UserProxyAgent."""
        super().__init__(name=name, description=description)
        self.input_func = input_func or cancellable_input
        self._is_async = iscoroutinefunction(self.input_func)

    @property
    def produced_message_types(self) -> Sequence[type[BaseChatMessage]]:
        """Message types this agent can produce."""
        return (TextMessage, HandoffMessage)

    def _get_latest_handoff(self, messages: Sequence[BaseChatMessage]) -> Optional[HandoffMessage]:
        """Find the HandoffMessage in the message sequence that addresses this agent."""
        if len(messages) > 0 and isinstance(messages[-1], HandoffMessage):
            if messages[-1].target == self.name:
                return messages[-1]
            else:
                raise RuntimeError(f"Handoff message target does not match agent name: {messages[-1].source}")
        return None

    async def _get_input(self, prompt: str, cancellation_token: Optional[CancellationToken]) -> str:
        """Handle input based on function signature."""
        try:
            if self._is_async:
                # Cast to AsyncInputFunc for proper typing
                async_func = cast(AsyncInputFunc, self.input_func)
                return await async_func(prompt, cancellation_token)
            else:
                # Cast to SyncInputFunc for proper typing
                sync_func = cast(SyncInputFunc, self.input_func)
                loop = asyncio.get_event_loop()
                return await loop.run_in_executor(None, sync_func, prompt)

        except asyncio.CancelledError:
            raise
        except Exception as e:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Ensure HandoffMessage.target exactly equals the receiving UserProxyAgent's name (case-sensitive).
  2. Don't call on_messages directly with handoff messages addressed elsewhere; let the team runtime route them.
  3. Fix the handoff target list/config that references the wrong agent name.

Example fix

// before
agent = UserProxyAgent(name="human")
await agent.on_messages([HandoffMessage(content="take over", target="Human", source="assistant")])

// after
agent = UserProxyAgent(name="human")
await agent.on_messages([HandoffMessage(content="take over", target="human", source="assistant")])
Defensive patterns

Strategy: validation

Validate before calling

def handoff_targets_agent(msgs, agent_name) -> bool:
    last = msgs[-1] if msgs else None
    return not isinstance(last, HandoffMessage) or last.target == agent_name

if handoff_targets_agent(messages, user_proxy.name):
    await user_proxy.on_messages(messages, ct)

Type guard

def is_handoff_for(msg, agent_name) -> bool:
    return isinstance(msg, HandoffMessage) and msg.target == agent_name

Try / catch

try:
    await user_proxy.on_messages(messages, ct)
except RuntimeError as e:
    if "target does not match" in str(e):
        # route to the correct agent instead
        target = next(a for a in team_agents if a.name == messages[-1].target)
        await target.on_messages(messages, ct)
    else:
        raise

Prevention

When it happens

Trigger: Calling user_proxy_agent.on_messages(...) / on_messages_stream(...) directly with a HandoffMessage addressed to a different agent; a team/handoff configuration where the handoff target name doesn't exactly match the UserProxyAgent's name (typo, case mismatch).

Common situations: Manual orchestration that forwards the full message history (including handoffs meant for other agents) to the user proxy; handoff targets defined with different casing or a renamed agent.

Related errors


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