microsoft/autogen · error · RuntimeError

Agent is already bound to a different runtime

Error message

Agent is already bound to a different runtime

What it means

The runtime half of bind_id_and_runtime: if the agent already carries a _runtime (from factory instantiation or a previous bind) and a different AgentRuntime instance is passed, RuntimeError is raised. An agent is permanently tied to the runtime that created it.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_base_agent.py:100

        assert self._id is not None
        return AgentMetadata(key=self._id.key, type=self._id.type, description=self._description)

    def __init__(self, description: str) -> None:
        if AgentInstantiationContext.is_in_factory_call():
            self._runtime: AgentRuntime = AgentInstantiationContext.current_runtime()
            self._id = AgentInstantiationContext.current_agent_id()
        if not isinstance(description, str):
            raise ValueError("Agent description must be a string")
        self._description = description

    async def bind_id_and_runtime(self, id: AgentId, runtime: AgentRuntime) -> None:
        if hasattr(self, "_id"):
            if self._id != id:
                raise RuntimeError("Agent is already bound to a different ID")

        if hasattr(self, "_runtime"):
            if self._runtime != runtime:
                raise RuntimeError("Agent is already bound to a different runtime")

        self._id = id
        self._runtime = runtime

    @property
    def type(self) -> str:
        return self.id.type

    @property
    def id(self) -> AgentId:
        return self._id

    @property
    def runtime(self) -> AgentRuntime:
        return self._runtime

    @final
    async def on_message(self, message: Any, ctx: MessageContext) -> Any:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Let each runtime instantiate its own agents via registered factories; never share agent instances across runtimes.
  2. When manually binding, construct the agent without a factory context first (so _runtime is unset), then bind once.
  3. Persist agent state (save_state) and load it (load_state) into a new runtime's instance rather than re-binding the old object.

Example fix

# before
agent = await runtime_a.get("t")
await agent.bind_id_and_runtime(agent.id, runtime_b)  # RuntimeError

# after
await MyAgent.register(runtime_b, "t", lambda: MyAgent("d"))
agent_b = await runtime_b.get("t")
await agent_b.load_state(await agent.save_state())
Defensive patterns

Strategy: validation

Validate before calling

if getattr(agent, "_runtime", None) is not None and agent._runtime is not runtime:
    raise RuntimeError("agent belongs to a different runtime")
await agent.bind_id_and_runtime(id, runtime)

Prevention

When it happens

Trigger: await agent.bind_id_and_runtime(id, other_runtime) where the agent was constructed inside runtime A's factory but bound to runtime B; moving agents between SingleThreadedAgentRuntime instances; tests sharing one agent across runtimes.

Common situations: Test setups creating a fresh runtime per test while reusing module-level agent instances; attempting to 'migrate' an agent to a new runtime after restart instead of letting the new runtime instantiate its own copy.

Related errors


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