{"record":{"id":"3a48ed3094a9c6f1","repo":"microsoft/autogen","slug":"agent-instances-must-be-the-same-object-type","errorCode":null,"errorMessage":"Agent instances must be the same object type.","messagePattern":"Agent instances must be the same object type\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py","lineNumber":936,"sourceCode":"        agent_instance: Agent,\n        agent_id: AgentId,\n    ) -> AgentId:\n        def agent_factory() -> Agent:\n            raise RuntimeError(\n                \"Agent factory was invoked for an agent instance that was not registered. This is likely due to the agent type being incorrectly subscribed to a topic. If this exception occurs when publishing a message to the DefaultTopicId, then it is likely that `skip_class_subscriptions` needs to be turned off when registering the agent.\"\n            )\n\n        if agent_id in self._instantiated_agents:\n            raise ValueError(f\"Agent with id {agent_id} already exists.\")\n\n        if agent_id.type not in self._agent_factories:\n            self._agent_factories[agent_id.type] = agent_factory\n            self._agent_instance_types[agent_id.type] = type_func_alias(agent_instance)\n        else:\n            if self._agent_factories[agent_id.type].__code__ != agent_factory.__code__:\n                raise ValueError(\"Agent factories and agent instances cannot be registered to the same type.\")\n            if self._agent_instance_types[agent_id.type] != type_func_alias(agent_instance):\n                raise ValueError(\"Agent instances must be the same object type.\")\n\n        await agent_instance.bind_id_and_runtime(id=agent_id, runtime=self)\n        self._instantiated_agents[agent_id] = agent_instance\n        return agent_id\n\n    async def _invoke_agent_factory(\n        self,\n        agent_factory: Callable[[], T | Awaitable[T]] | Callable[[AgentRuntime, AgentId], T | Awaitable[T]],\n        agent_id: AgentId,\n    ) -> T:\n        with AgentInstantiationContext.populate_context((self, agent_id)):\n            try:\n                if len(inspect.signature(agent_factory).parameters) == 0:\n                    factory_one = cast(Callable[[], T], agent_factory)\n                    agent = factory_one()\n                elif len(inspect.signature(agent_factory).parameters) == 2:\n                    warnings.warn(\n                        \"Agent factories that take two arguments are deprecated. Use AgentInstantiationContext instead. Two arg factories will be removed in a future version.\",","sourceCodeStart":918,"sourceCodeEnd":954,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py#L918-L954","documentation":"When register_agent_instance adds a second instance under a type that already has instance registrations (the sentinel-factory path matched), it checks that the new instance's concrete class equals the recorded _agent_instance_types[type]. A different class under the same type string raises ValueError, because try_get_underlying_agent_instance promises one concrete type per agent type.","triggerScenarios":"Registering instance of class A as AgentId(\"handler\", \"1\"), then registering an instance of class B (not the same class) as AgentId(\"handler\", \"2\"). Subclass instances also fail if the first registration set the type to the parent.","commonSituations":"Registering per-tenant or per-shard instances where someone swapped in a different implementation class for one key; evolving to a new agent class but keeping the old type string with mixed old/new instances during migration.","solutions":["Use a separate AgentType string per implementation class (e.g. 'handler.v1' vs 'handler.v2')","Ensure all instances registered under one type are exactly the same class (register the subclass everywhere, not just some keys)","During migration, finish swapping all instances before running, or register the new class under a new type"],"exampleFix":"# before\nawait runtime.register_agent_instance(V1(), AgentId(\"handler\", \"1\"))\nawait runtime.register_agent_instance(V2(), AgentId(\"handler\", \"2\"))  # ValueError\n\n# after\nawait runtime.register_agent_instance(V1(), AgentId(\"handler.v1\", \"1\"))\nawait runtime.register_agent_instance(V2(), AgentId(\"handler.v2\", \"2\"))","handlingStrategy":"validation","validationCode":"def instances_same_class(runtime, t: str, new_instance) -> bool:\n    recorded = runtime._agent_instance_types.get(t)\n    return recorded is None or recorded is type(new_instance)","typeGuard":"def matches_recorded_type(recorded_type, instance) -> bool:\n    return type(instance) is recorded_type","tryCatchPattern":"try:\n    await runtime.register_agent_instance(inst2, AgentId(t, \"2\"))\nexcept ValueError as e:\n    if \"same object type\" in str(e):\n        await runtime.register_agent_instance(inst2, AgentId(type(inst2).__name__.lower(), \"2\"))\n    else:\n        raise","preventionTips":["One concrete class per agent type string; version via new type names","Assert class consistency in bootstrap before registering many instances","Avoid mixing parent and subclass instances under one type"],"tags":["autogen-core","agent-registration","instance","type-mismatch"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}