microsoft/autogen · error · ValueError
The first participant must be able to produce a handoff mess
Error message
The first participant must be able to produce a handoff messages.
What it means
Swarm.__init__ raises ValueError when the first participant does not declare HandoffMessage in its produced_message_types. The swarm starts by letting the first agent speak, and control transfer only happens via handoff messages — an agent that cannot produce them dead-ends the run at turn one.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_swarm_group_chat.py:264
if not isinstance(participant, ChatAgent):
raise TypeError(f"Participant {participant} must be a ChatAgent.")
super().__init__(
name=name or self.DEFAULT_NAME,
description=description or self.DEFAULT_DESCRIPTION,
participants=[participant for participant in participants],
group_chat_manager_name="SwarmGroupChatManager",
group_chat_manager_class=SwarmGroupChatManager,
termination_condition=termination_condition,
max_turns=max_turns,
runtime=runtime,
custom_message_types=custom_message_types,
emit_team_events=emit_team_events,
)
# The first participant must be able to produce handoff messages.
first_participant = self._participants[0]
assert isinstance(first_participant, ChatAgent)
if HandoffMessage not in first_participant.produced_message_types:
raise ValueError("The first participant must be able to produce a handoff messages.")
def _create_group_chat_manager_factory(
self,
name: str,
group_topic_type: str,
output_topic_type: str,
participant_topic_types: List[str],
participant_names: List[str],
participant_descriptions: List[str],
output_message_queue: asyncio.Queue[BaseAgentEvent | BaseChatMessage | GroupChatTermination],
termination_condition: TerminationCondition | None,
max_turns: int | None,
message_factory: MessageFactory,
) -> Callable[[], SwarmGroupChatManager]:
def _factory() -> SwarmGroupChatManager:
return SwarmGroupChatManager(
name,
group_topic_type,View on GitHub (pinned to 027ecf0a37)
Solutions
- Make the first participant an AssistantAgent or an agent whose produced_message_types includes HandoffMessage.
- In a custom ChatAgent class, set produced_message_types = (HandoffMessage, TextMessage, MultiModalMessage) (as applicable).
- Reorder participants so a handoff-capable agent is first.
Example fix
# before
class EntryAgent(ChatAgent):
produced_message_types = (TextMessage,) # ValueError as first participant
# after
from autogen_agentchat.messages import HandoffMessage, TextMessage
class EntryAgent(ChatAgent):
produced_message_types = (HandoffMessage, TextMessage) Defensive patterns
Strategy: type-guard
Validate before calling
from autogen_agentchat.messages import HandoffMessage first = participants[0] assert HandoffMessage in first.produced_message_types, "First swarm participant must produce HandoffMessage"
Type guard
from autogen_agentchat.agents import ChatAgent
from autogen_agentchat.messages import HandoffMessage
def can_produce_handoff(agent: ChatAgent) -> bool:
return HandoffMessage in agent.produced_message_types Prevention
- Put an AssistantAgent (handoff-capable by default) first in the Swarm participant list.
- For custom ChatAgent classes, always include HandoffMessage in produced_message_types.
When it happens
Trigger: The first participant is a ChatAgent subclass whose produced_message_types omits HandoffMessage (e.g. a custom agent or one configured without handoffs); AssistantAgent instances include it by default, custom agents often forget it.
Common situations: Writing a custom ChatAgent for swarm entry; reordering participants so a non-handoff agent lands first; porting agents from older versions where produced_message_types handling differed.
Related errors
- The target {message.target} is not one of the participants {
- The existing handoff target {existing_message.target} is not
- Participant {participant} must be a ChatAgent.
- Handoff name '{name}' is not a valid identifier.
- Agent state for {name} not found in the saved state.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/7bd1ded6ee46e35c.
Report an issue: GitHub.