{"record":{"id":"005bcd767445ca09","repo":"microsoft/autogen","slug":"termination-condition-has-already-been-reached-005bcd","errorCode":null,"errorMessage":"Termination condition has already been reached","messagePattern":"Termination condition has already been reached","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-agentchat/src/autogen_agentchat/base/_termination.py","lineNumber":158,"sourceCode":"    conditions: List[ComponentModel]\n    \"\"\"List of termination conditions where any one being satisfied is sufficient.\"\"\"\n\n\nclass OrTerminationCondition(TerminationCondition, Component[OrTerminationConditionConfig]):\n    component_config_schema = OrTerminationConditionConfig\n    component_type = \"termination\"\n    component_provider_override = \"autogen_agentchat.base.OrTerminationCondition\"\n\n    def __init__(self, *conditions: TerminationCondition) -> None:\n        self._conditions = conditions\n\n    @property\n    def terminated(self) -> bool:\n        return any(condition.terminated for condition in self._conditions)\n\n    async def __call__(self, messages: Sequence[BaseAgentEvent | BaseChatMessage]) -> StopMessage | None:\n        if self.terminated:\n            raise RuntimeError(\"Termination condition has already been reached\")\n        stop_messages = await asyncio.gather(*[condition(messages) for condition in self._conditions])\n        stop_messages_filter = [stop_message for stop_message in stop_messages if stop_message is not None]\n        if len(stop_messages_filter) > 0:\n            content = \", \".join(stop_message.content for stop_message in stop_messages_filter)\n            source = \", \".join(stop_message.source for stop_message in stop_messages_filter)\n            return StopMessage(content=content, source=source)\n        return None\n\n    async def reset(self) -> None:\n        for condition in self._conditions:\n            await condition.reset()\n\n    def _to_config(self) -> OrTerminationConditionConfig:\n        \"\"\"Convert the OR termination condition to a config.\"\"\"\n        return OrTerminationConditionConfig(conditions=[condition.dump_component() for condition in self._conditions])\n\n    @classmethod\n    def _from_config(cls, config: OrTerminationConditionConfig) -> Self:","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-agentchat/src/autogen_agentchat/base/_termination.py#L140-L176","documentation":"OrTerminationCondition raises RuntimeError (note: not TerminatedException like the other conditions — a known inconsistency) if called after any of its sub-conditions has already terminated. The terminated property is any(condition.terminated), so a single fired sub-condition locks the whole Or condition.","triggerScenarios":"Invoking await or_condition(messages) after one sub-condition already returned a StopMessage; sharing sub-conditions between an OrTerminationCondition and a team's own condition; calling a run loop a second time without resetting the Or condition.","commonSituations":"Composing OrTerminationCondition(MaxMessageTermination(5), TimeoutTermination(60)) and reusing it across team runs; catching only TerminatedException and missing this RuntimeError variant.","solutions":["Check or_condition.terminated before calling it","await or_condition.reset() (or team.reset()) between runs","When catching, handle both exception types: except (TerminatedException, RuntimeError) — this site raises bare RuntimeError"],"exampleFix":"# before\nstop = await or_condition(messages)  # raises RuntimeError after termination\n\n# after\nstop = None if or_condition.terminated else await or_condition(messages)","handlingStrategy":"validation","validationCode":"if or_cond.terminated:\n    await or_cond.reset()\nstop = await or_cond(messages)","typeGuard":null,"tryCatchPattern":"# NOTE: this site raises bare RuntimeError, not TerminatedException\ntry:\n    stop = await or_cond(messages)\nexcept (RuntimeError, TerminatedException) as e:  # from autogen_agentchat.conditions import TerminatedException\n    if \"already been reached\" in str(e):\n        await or_cond.reset()\n        stop = await or_cond(messages)\n    else:\n        raise","preventionTips":["Catch both RuntimeError and TerminatedException for Or conditions — the exception types are inconsistent across the library","Reset the Or condition (or the team) between runs","Do not reuse sub-condition instances across multiple composites"],"tags":["termination","stateful","or-termination","runtimeerror","agentchat"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}