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
- Ensure HandoffMessage.target exactly equals the receiving UserProxyAgent's name (case-sensitive).
- Don't call on_messages directly with handoff messages addressed elsewhere; let the team runtime route them.
- 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
- Define handoff targets from the agents' name attributes, never from free-text strings.
- Assert HandoffMessage.target == receiving_agent.name before calling on_messages directly.
- Prefer team-level routing (Selector/Swarm) over manual on_messages forwarding.
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
- Handoff name '{name}' is not a valid identifier.
- Target is null.
- Handoff name must be a string: {values['name']}
- Handoff name must be a valid identifier: {values['name']}
- The target {message.target} is not one of the participants {
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/349943344947b072.
Report an issue: GitHub.