{"record":{"id":"c157957a6d7bce43","repo":"microsoft/autogen","slug":"the-existing-handoff-target-existing-message-targ","errorCode":null,"errorMessage":"The existing handoff target {existing_message.target} is not one of the participants {self._participant_names}. If you are resuming Swarm with a new task make sure to include in your task a HandoffMessage with a valid participant as the target. For example, if you are resuming from a HandoffTermination, make sure the new task is a HandoffMessage with a valid participant as the target.","messagePattern":"The existing handoff target (.+?) is not one of the participants (.+?)\\. If you are resuming Swarm with a new task make sure to include in your task a HandoffMessage with a valid participant as the target\\. For example, if you are resuming from a HandoffTermination, make sure the new task is a HandoffMessage with a valid participant as the target\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_swarm_group_chat.py","lineNumber":64,"sourceCode":"\n    async def validate_group_state(self, messages: List[BaseChatMessage] | None) -> None:\n        \"\"\"Validate the start messages for the group chat.\"\"\"\n        # Check if any of the start messages is a handoff message.\n        if messages:\n            for message in messages:\n                if isinstance(message, HandoffMessage):\n                    if message.target not in self._participant_names:\n                        raise ValueError(\n                            f\"The target {message.target} is not one of the participants {self._participant_names}. \"\n                            \"If you are resuming Swarm with a new HandoffMessage make sure to set the target to a valid participant as the target.\"\n                        )\n                    return\n\n        # Check if there is a handoff message in the thread that is not targeting a valid participant.\n        for existing_message in reversed(self._message_thread):\n            if isinstance(existing_message, HandoffMessage):\n                if existing_message.target not in self._participant_names:\n                    raise ValueError(\n                        f\"The existing handoff target {existing_message.target} is not one of the participants {self._participant_names}. \"\n                        \"If you are resuming Swarm with a new task make sure to include in your task \"\n                        \"a HandoffMessage with a valid participant as the target. For example, if you are \"\n                        \"resuming from a HandoffTermination, make sure the new task is a HandoffMessage \"\n                        \"with a valid participant as the target.\"\n                    )\n                # The latest handoff message should always target a valid participant.\n                # Do not look past the latest handoff message.\n                return\n\n    async def reset(self) -> None:\n        self._current_turn = 0\n        self._message_thread.clear()\n        if self._termination_condition is not None:\n            await self._termination_condition.reset()\n        self._current_speaker = self._participant_names[0]\n\n    async def select_speaker(self, thread: Sequence[BaseAgentEvent | BaseChatMessage]) -> List[str] | str:","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_swarm_group_chat.py#L46-L82","documentation":"SwarmGroupChatManager.validate_group_state raises ValueError when the most recent HandoffMessage already in the saved message thread targets a name that is not a current participant. On resume, the swarm continues from the latest handoff, so that target must exist in the reloaded team.","triggerScenarios":"Saving a swarm state (save_state), reconstructing the team with a different/renamed participant set, then loading the state and running a new task; the thread's latest HandoffMessage targets the old name.","commonSituations":"Resume-from-handoff workflows where participants were renamed between sessions; serializing state in one process and resuming in another with a different roster.","solutions":["Reconstruct the Swarm with the same participant names as when the state was saved.","Alternatively, start the new task with a HandoffMessage targeting a valid participant — but the check still inspects the existing thread, so renaming participants on resume is not supported; keep names stable.","If you must rename, re-serialize the thread and rewrite the latest handoff target to a valid participant name before loading state."],"exampleFix":"# before\n# state saved when participants were ['researcher', 'coder']\nswarm = Swarm(participants=[researcher, \"programmer\"])  # renamed -> resume fails\nawait swarm.load_state(saved)\n\n# after\nswarm = Swarm(participants=[researcher, coder])  # keep names identical to saved state\nawait swarm.load_state(saved)","handlingStrategy":"validation","validationCode":"# Before load_state: ensure participant names match those used when state was saved\nsaved_targets = [m.target for m in saved_thread if isinstance(m, HandoffMessage)]\nassert all(t in [a.name for a in agents] for t in saved_targets)","typeGuard":null,"tryCatchPattern":"try:\n    await team.run(task=new_task)\nexcept ValueError as e:\n    if \"existing handoff target\" in str(e):\n        raise ValueError(\"Participant names changed since state save; rebuild with original names\") from e\n    raise","preventionTips":["Keep participant names stable across save/load/resume sessions.","When resuming from HandoffTermination, always send a new HandoffMessage with a valid target."],"tags":["autogen","swarm","handoff","state","resume"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}