{"record":{"id":"8007405533c1885b","repo":"microsoft/autogen","slug":"agent-instances-must-be-the-same-object-type-800740","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-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py","lineNumber":767,"sourceCode":"        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            await self._register_agent_type(agent_id.type)\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            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.\",\n                    stacklevel=2,","sourceCodeStart":749,"sourceCodeEnd":785,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py#L749-L785","documentation":"When several agent instances are registered under the same type string, register_agent_instance enforces that they all share one concrete class: it compares type_func_alias(agent_instance) against the recorded self._agent_instance_types[agent_id.type]. A mismatch raises ValueError('Agent instances must be the same object type.'). This keeps the type name meaningful for serialization and subscription purposes — one type must map to one agent class.","triggerScenarios":"Registering instance A of class X under AgentId('t','k1'), then instance B of class Y under AgentId('t','k2') where X != Y; subclassing an agent and registering the subclass alongside its base under the same type name; copy-pasting registration code with a different agent class but the same type string.","commonSituations":"Multi-agent setups where each agent gets its own key but someone reused the type; refactoring one agent to a subclass while old registrations still use the base class; heterogeneous worker pools accidentally sharing type names.","solutions":["Give each distinct agent class its own type string (register AgentId(MyClass.__name__, key))","If one type must serve several keys, ensure every instance registered under it is exactly the same class","After refactoring an agent class, re-register all instances of that type in the same run with the new class","Add an assertion in test/setup code that type_func_alias of all instances matches before registering"],"exampleFix":"# before\nawait runtime.register_agent_instance(AssistantAgent(), AgentId('agent', 'one'))\nawait runtime.register_agent_instance(CriticAgent(), AgentId('agent', 'two'))  # ValueError\n\n# after\nawait runtime.register_agent_instance(AssistantAgent(), AgentId('assistant', 'one'))\nawait runtime.register_agent_instance(CriticAgent(), AgentId('critic', 'two'))","handlingStrategy":"type-guard","validationCode":"instance_types = getattr(runtime, '_agent_instance_types', {})\ndef same_class(runtime, type_str: str, instance) -> bool:\n    recorded = instance_types.get(type_str)\n    return recorded is None or recorded is type(instance)","typeGuard":"def instances_compatible(runtime, type_str: str, instance) -> bool:\n    recorded = getattr(runtime, '_agent_instance_types', {}).get(type_str)\n    return recorded is None or recorded is type(instance)","tryCatchPattern":"try:\n    await runtime.register_agent_instance(agent, AgentId(t, k))\nexcept ValueError as e:\n    if 'same object type' in str(e):\n        raise ValueError(f'type {t!r} already holds class {instance_types[t]!r}') from e\n    raise","preventionTips":["One agent class per type string; derive type from the class name","Assert type(instance) matches before registering additional keys","Re-register all instances after refactoring an agent class","Document the class->type mapping in project docs"],"tags":["registration","type-mismatch","agent-instance"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}