{"record":{"id":"a4a533f47642cc9c","repo":"microsoft/autogen","slug":"factory-registered-using-the-wrong-type-expected","errorCode":null,"errorMessage":"Factory registered using the wrong type: expected {expected_class.__name__}, got {type_func_alias(agent_instance).__name__}","messagePattern":"Factory registered using the wrong type: expected (.+?), got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py","lineNumber":907,"sourceCode":"        agent_factory: Callable[[], T | Awaitable[T]],\n        *,\n        expected_class: type[T] | None = None,\n    ) -> AgentType:\n        if isinstance(type, str):\n            type = AgentType(type)\n\n        if type.type in self._agent_factories:\n            raise ValueError(f\"Agent with type {type} already exists.\")\n\n        async def factory_wrapper() -> T:\n            maybe_agent_instance = agent_factory()\n            if inspect.isawaitable(maybe_agent_instance):\n                agent_instance = await maybe_agent_instance\n            else:\n                agent_instance = maybe_agent_instance\n\n            if expected_class is not None and not issubclass(type_func_alias(agent_instance), expected_class):\n                raise ValueError(\n                    f\"Factory registered using the wrong type: expected {expected_class.__name__}, got {type_func_alias(agent_instance).__name__}\"\n                )\n            return agent_instance\n\n        self._agent_factories[type.type] = factory_wrapper\n\n        return type\n\n    async def register_agent_instance(\n        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","sourceCodeStart":889,"sourceCodeEnd":925,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py#L889-L925","documentation":"Inside the factory wrapper created by register_factory, if expected_class was supplied and the produced instance's class is not a subclass of expected_class, a ValueError is raised at agent instantiation time (not at registration). This guards runtime.type-based casts (e.g. try_get_underlying_agent_instance(T)) against factories returning an unexpected class.","triggerScenarios":"register_factory(type, factory, expected_class=B) where factory returns A (A not a subclass of B, including cases where the factory was copy-pasted and constructs the old agent class); async factories returning a coroutine that resolves to the wrong class; refactoring an agent class without updating expected_class at the registration site.","commonSituations":"Copy-pasted registration blocks after creating a new agent variant; renaming/splitting agent classes so isinstance relationships break; passing expected_class=Agent but factory returns a non-Agent helper object.","solutions":["Make the factory construct the same class (or subclass) passed as expected_class; align the generic type parameter, registration call, and constructed class","Drop expected_class if you intentionally register heterogeneous factories under one type (then handle typing at retrieval)","If the class was renamed, update expected_class to the new name"],"exampleFix":"# before\nawait runtime.register_factory(\n    AgentType(\"worker\"), lambda: OldWorker(), expected_class=NewWorker\n)\n\n# after\nawait runtime.register_factory(\n    AgentType(\"worker\"), NewWorker.create, expected_class=NewWorker\n)","handlingStrategy":"type-guard","validationCode":"def factory_returns_subclass(factory, expected) -> bool:\n    import inspect\n    hints = inspect.signature(factory).return_annotation\n    # runtime-proof: dry-run the factory in a sandbox when cheap\n    try:\n        inst = factory()\n        import inspect as i\n        if i.isawaitable(inst):\n            inst = await_early(inst)  # only if sync-safe\n        return isinstance(inst, expected)\n    except Exception:\n        return True  # defer check to runtime","typeGuard":"def instance_matches_expected(instance, expected_class) -> bool:\n    return expected_class is None or isinstance(instance, expected_class)","tryCatchPattern":"try:\n    agent = await runtime.try_get_underlying_agent_instance(agent_id, WorkerAgent)\nexcept ValueError as e:\n    if \"wrong type\" in str(e):\n        log_registration_bug(agent_id, expected=WorkerAgent)\n    raise","preventionTips":["Use the type-safe RuntimeAgentType registration API so expected_class is derived, not hand-written","Keep one registration block per agent class next to its definition","Unit-test each factory returns the registered class"],"tags":["autogen-core","agent-registration","factory","type-mismatch"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}