microsoft/autogen · error · ValueError

Agent instances must be the same object type.

Error message

Agent instances must be the same object type.

What it means

When several agent instances are registered under the same type string, register_agent_instance enforces that they all share one concrete class: it compares type_func_alias(agent_instance) against the recorded self._agent_instance_types[agent_id.type]. A mismatch raises ValueError('Agent instances must be the same object type.'). This keeps the type name meaningful for serialization and subscription purposes — one type must map to one agent class.

Source

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

        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(
                    "Agent factories that take two arguments are deprecated. Use AgentInstantiationContext instead. Two arg factories will be removed in a future version.",
                    stacklevel=2,

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Give each distinct agent class its own type string (register AgentId(MyClass.__name__, key))
  2. If one type must serve several keys, ensure every instance registered under it is exactly the same class
  3. After refactoring an agent class, re-register all instances of that type in the same run with the new class
  4. Add an assertion in test/setup code that type_func_alias of all instances matches before registering

Example fix

# before
await runtime.register_agent_instance(AssistantAgent(), AgentId('agent', 'one'))
await runtime.register_agent_instance(CriticAgent(), AgentId('agent', 'two'))  # ValueError

# after
await runtime.register_agent_instance(AssistantAgent(), AgentId('assistant', 'one'))
await runtime.register_agent_instance(CriticAgent(), AgentId('critic', 'two'))
Defensive patterns

Strategy: type-guard

Validate before calling

instance_types = getattr(runtime, '_agent_instance_types', {})
def same_class(runtime, type_str: str, instance) -> bool:
    recorded = instance_types.get(type_str)
    return recorded is None or recorded is type(instance)

Type guard

def instances_compatible(runtime, type_str: str, instance) -> bool:
    recorded = getattr(runtime, '_agent_instance_types', {}).get(type_str)
    return recorded is None or recorded is type(instance)

Try / catch

try:
    await runtime.register_agent_instance(agent, AgentId(t, k))
except ValueError as e:
    if 'same object type' in str(e):
        raise ValueError(f'type {t!r} already holds class {instance_types[t]!r}') from e
    raise

Prevention

When it happens

Trigger: Registering instance A of class X under AgentId('t','k1'), then instance B of class Y under AgentId('t','k2') where X != Y; subclassing an agent and registering the subclass alongside its base under the same type name; copy-pasting registration code with a different agent class but the same type string.

Common situations: Multi-agent setups where each agent gets its own key but someone reused the type; refactoring one agent to a subclass while old registrations still use the base class; heterogeneous worker pools accidentally sharing type names.

Related errors


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