{"record":{"id":"ee1851faeb2f426b","repo":"microsoft/autogen","slug":"agent-factories-and-agent-instances-cannot-be-regi-ee1851","errorCode":null,"errorMessage":"Agent factories and agent instances cannot be registered to the same type.","messagePattern":"Agent factories and agent instances cannot be registered to the same type\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py","lineNumber":765,"sourceCode":"        self,\n        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            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(","sourceCodeStart":747,"sourceCodeEnd":783,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py#L747-L783","documentation":"register_agent_instance distinguishes two regimes for a type key: a real factory registered via register_factory, or the placeholder factory installed for instance-based types (compared by __code__ identity). If a type already has a factory whose code object differs from the placeholder — i.e. it came from register_factory — and you then try to register an instance under that same type, it raises ValueError('Agent factories and agent instances cannot be registered to the same type.'). The runtime forbids mixing both supply modes for one type because message routing would be ambiguous.","triggerScenarios":"Calling await runtime.register_factory('t', ...) and later await runtime.register_agent_instance(agent, AgentId('t', 'k')) on the same runtime (or the reverse order); framework-internal class registration already putting a factory under the type before you register an instance with that name; re-registering after a partial setup that added the factory.","commonSituations":"Migrating an agent from factory-based to instance-based registration without changing the type string; generic helper code that sometimes registers factories and sometimes instances under the same name; name collisions between a class-registered agent type and a hand-named instance id.","solutions":["Use a different type name for the instance registration than any factory-registered type","Standardize on one registration mode per type: register_factory for stateless/on-demand agents, register_agent_instance for single pre-built objects","If you must switch modes, do it before any registration of that type (fresh runtime) — there is no unregister API","Audit all register_* calls in the process to find the earlier factory registration that claimed the name"],"exampleFix":"# before\nawait runtime.register_factory('assistant', lambda: AssistantAgent())\nagent = AssistantAgent()\nawait runtime.register_agent_instance(agent, AgentId('assistant', 'a'))  # ValueError\n\n# after: pick one mode per type name\nawait runtime.register_factory('assistant', lambda: AssistantAgent())\n# OR\nawait runtime.register_agent_instance(agent, AgentId('assistant_instance', 'a'))","handlingStrategy":"validation","validationCode":"def type_has_factory(runtime, type_str: str) -> bool:\n    return type_str in getattr(runtime, '_agent_factories', {})","typeGuard":null,"tryCatchPattern":"try:\n    await runtime.register_agent_instance(agent, AgentId(t, k))\nexcept ValueError as e:\n    if 'cannot be registered to the same type' in str(e):\n        raise ValueError(f'type {t!r} already factory-registered; choose another name') from e\n    raise","preventionTips":["Pick one supply mode per type name: factory OR instance","Use distinct names when switching an agent from factory to instance registration","Keep a manifest of which types are factory vs instance registered","Register before any framework class-subscription claims the name"],"tags":["registration","conflict","factory","agent-instance"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}