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
- Use a different type name for the instance registration than any factory-registered type
- Standardize on one registration mode per type: register_factory for stateless/on-demand agents, register_agent_instance for single pre-built objects
- If you must switch modes, do it before any registration of that type (fresh runtime) — there is no unregister API
- 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
- Pick one supply mode per type name: factory OR instance
- Use distinct names when switching an agent from factory to instance registration
- Keep a manifest of which types are factory vs instance registered
- Register before any framework class-subscription claims the name
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
- Agent factories and agent instances cannot be registered to
- Factory registered using the wrong type.
- Agent instances must be the same object type.
- Message type {message_type} is already registered.
- Message type {message_type} must be a subclass of BaseChatMe
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/ee1851faeb2f426b.
Report an issue: GitHub.