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

In register_agent_instance, when the agent_id.type already has an entry in _agent_factories, the runtime compares code objects: if the existing factory is a real factory (registered via register_factory) rather than the instance sentinel, it raises ValueError. One type string cannot be backed by both a callable factory and a directly-registered instance.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_single_threaded_agent_runtime.py:934

    async def register_agent_instance(
        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
            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)):
            try:
                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:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Use a distinct AgentType string for instance-registered agents vs factory-registered ones (e.g. 'worker' vs 'worker-singleton')
  2. Convert the instance to a factory: register_factory returning the pre-built instance (with skip_class_subscriptions if needed)
  3. Standardize on one registration style per type across the codebase

Example fix

# before
await runtime.register_factory(AgentType("worker"), Worker.create)
await runtime.register_agent_instance(w, AgentId("worker", "1"))  # ValueError

# after
await runtime.register_factory(AgentType("worker"), Worker.create)
await runtime.register_agent_instance(w, AgentId("worker_singleton", "1"))
Defensive patterns

Strategy: validation

Validate before calling

async def can_register_instance(runtime, agent_id) -> bool:
    factory = runtime._agent_factories.get(agent_id.type)
    return factory is None  # must not collide with a real factory

Type guard

def type_is_factory_free(runtime, t: str) -> bool:
    return t not in runtime._agent_factories

Try / catch

try:
    await runtime.register_agent_instance(agent, agent_id)
except ValueError as e:
    if "cannot be registered to the same type" in str(e):
        await runtime.register_agent_instance(agent, AgentId(agent_id.type + '_singleton', agent_id.key))
    else:
        raise

Prevention

When it happens

Trigger: First calling await runtime.register_factory(AgentType("worker"), factory), then await runtime.register_agent_instance(inst, AgentId("worker", "1")) (or the reverse order for another key) — the second registration detects the mismatch between factory code and the instance sentinel and fails.

Common situations: Hybrid designs where some workers are factories and one 'singleton' is an instance under the same type name; refactoring from instance registration to factory registration without renaming the type; copy-paste across setups that pick the opposite registration style for the same name.

Related errors


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