microsoft/autogen · error · ValueError

Agent factories and agent instances cannot be registered to

Error message

Agent factories and agent instances cannot be registered to the same type.

What it means

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.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py:765

        self,
        agent_instance: Agent,
        agent_id: AgentId,
    ) -> AgentId:
        def agent_factory() -> Agent:
            raise RuntimeError(
                "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."
            )

        if agent_id in self._instantiated_agents:
            raise ValueError(f"Agent with id {agent_id} already exists.")

        if agent_id.type not in self._agent_factories:
            self._agent_factories[agent_id.type] = agent_factory
            await self._register_agent_type(agent_id.type)
            self._agent_instance_types[agent_id.type] = type_func_alias(agent_instance)
        else:
            if self._agent_factories[agent_id.type].__code__ != agent_factory.__code__:
                raise ValueError("Agent factories and agent instances cannot be registered to the same type.")
            if self._agent_instance_types[agent_id.type] != type_func_alias(agent_instance):
                raise ValueError("Agent instances must be the same object type.")

        await agent_instance.bind_id_and_runtime(id=agent_id, runtime=self)
        self._instantiated_agents[agent_id] = agent_instance
        return agent_id

    async def _invoke_agent_factory(
        self,
        agent_factory: Callable[[], T | Awaitable[T]] | Callable[[AgentRuntime, AgentId], T | Awaitable[T]],
        agent_id: AgentId,
    ) -> T:
        with AgentInstantiationContext.populate_context((self, agent_id)):
            if len(inspect.signature(agent_factory).parameters) == 0:
                factory_one = cast(Callable[[], T], agent_factory)
                agent = factory_one()
            elif len(inspect.signature(agent_factory).parameters) == 2:
                warnings.warn(

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Use a different type name for the instance registration than any factory-registered type
  2. Standardize on one registration mode per type: register_factory for stateless/on-demand agents, register_agent_instance for single pre-built objects
  3. If you must switch modes, do it before any registration of that type (fresh runtime) — there is no unregister API
  4. Audit all register_* calls in the process to find the earlier factory registration that claimed the name

Example fix

# before
await runtime.register_factory('assistant', lambda: AssistantAgent())
agent = AssistantAgent()
await runtime.register_agent_instance(agent, AgentId('assistant', 'a'))  # ValueError

# after: pick one mode per type name
await runtime.register_factory('assistant', lambda: AssistantAgent())
# OR
await runtime.register_agent_instance(agent, AgentId('assistant_instance', 'a'))
Defensive patterns

Strategy: validation

Validate before calling

def type_has_factory(runtime, type_str: str) -> bool:
    return type_str in getattr(runtime, '_agent_factories', {})

Try / catch

try:
    await runtime.register_agent_instance(agent, AgentId(t, k))
except ValueError as e:
    if 'cannot be registered to the same type' in str(e):
        raise ValueError(f'type {t!r} already factory-registered; choose another name') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/ee1851faeb2f426b. Report an issue: GitHub.