{"record":{"id":"4621bbd747ff731c","repo":"microsoft/autogen","slug":"factory-registered-using-the-wrong-type","errorCode":null,"errorMessage":"Factory registered using the wrong type.","messagePattern":"Factory registered using the wrong type\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py","lineNumber":736,"sourceCode":"        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        if self._host_connection is None:\n            raise RuntimeError(\"Host connection is not set.\")\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 type_func_alias(agent_instance) != expected_class:\n                raise ValueError(\"Factory registered using the wrong type.\")\n\n            return agent_instance\n\n        self._agent_factories[type.type] = factory_wrapper\n        # Send the registration request message to the host.\n        await self._register_agent_type(type.type)\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            )","sourceCodeStart":718,"sourceCodeEnd":754,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py#L718-L754","documentation":"register_factory accepts an optional expected_class parameter. When the wrapped factory runs and the produced object's type() does not equal expected_class, the wrapper raises ValueError('Factory registered using the wrong type.'). This is a programmatic assertion that the declared type matches what the factory actually constructs, catching mismatches before the agent enters message processing.","triggerScenarios":"Passing expected_class=X while the factory returns a subclass, a different class, or None; type_func_alias(agent_instance) (the instance's concrete type) differing from expected_class — note subclass instances fail because the comparison is exact type equality, not isinstance; factories whose return value depends on runtime state and can return different classes.","commonSituations":"Registering with expected_class=BaseAgent while the factory builds MyAgent(BaseAgent) — exact-type comparison rejects it; refactoring that changes what a factory returns without updating expected_class; factories returning None on a failed initialization path.","solutions":["Pass expected_class that is exactly the class the factory instantiates (or omit expected_class entirely if you rely on subclassing)","Update expected_class after refactoring the factory's return type","Fix the factory so it cannot return None or an alternative class on any code path","If subclass support is needed, drop expected_class and do your own isinstance validation inside the factory"],"exampleFix":"# before\nawait runtime.register_factory(\n    'agent', lambda: MyAgent(), expected_class=BaseAgent  # ValueError: MyAgent != BaseAgent\n)\n\n# after\nawait runtime.register_factory('agent', lambda: MyAgent(), expected_class=MyAgent)\n# or simply omit expected_class","handlingStrategy":"validation","validationCode":"def factory_ok(factory, expected_class) -> bool:\n    import inspect\n    if inspect.isawaitable(factory):\n        return False\n    return True  # verify by trial instantiation instead:\n# trial = factory(); assert type(trial) is expected_class","typeGuard":null,"tryCatchPattern":"try:\n    agent = await runtime._get_agent(agent_id)  # triggers factory_wrapper\nexcept ValueError as e:\n    if 'wrong type' in str(e):\n        raise TypeError('expected_class does not match factory output') from e\n    raise","preventionTips":["Pass expected_class equal to the exact class the factory constructs, or omit it","Trial-instantiate the factory in tests and assert type(obj) is expected_class","Remember the check is exact type equality — subclasses fail","Update expected_class whenever the factory's return class changes"],"tags":["registration","type-mismatch","factory"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}