microsoft/autogen · error · RuntimeError
Agent factory was invoked for an agent instance that was not
Error message
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.
What it means
When you register a concrete agent instance, the runtime installs a placeholder factory whose only job is to raise RuntimeError if it is ever invoked, because no factory exists for that instance-based type. The placeholder fires when the worker must materialize an agent for an AgentId whose exact key was never registered as an instance — i.e. a subscription delivered a message to agent key the worker does not hold. The long message text guides you to the two usual root causes: a bad topic subscription, or class-level default subscriptions colliding on DefaultTopicId when skip_class_subscriptions was set incorrectly.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py:752
if expected_class is not None and type_func_alias(agent_instance) != expected_class:
raise ValueError("Factory registered using the wrong type.")
return agent_instance
self._agent_factories[type.type] = factory_wrapper
# Send the registration request message to the host.
await self._register_agent_type(type.type)
return type
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
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_instanceView on GitHub (pinned to 027ecf0a37)
Solutions
- Switch from register_agent_instance to register_factory for that type so any AgentId key can be instantiated on demand
- Fix the subscription topology so the topic only delivers to the exact registered AgentId (use explicit subscriptions instead of class defaults)
- Register instances for every key that can receive messages, or publish directly to the agent id rather than a shared topic
- Audit topic/subscription configuration on both host and worker to ensure instance-registered types are not subscribed to DefaultTopicId
Example fix
# before
agent = MyAgent()
await runtime.register_agent_instance(agent, AgentId('my_agent', 'default'))
await runtime.add_subscription(TypeSubscription(topic_type='default', agent_type='my_agent'))
# publishing to default topic -> other keys hit the placeholder -> RuntimeError
# after
await runtime.register_factory('my_agent', lambda: MyAgent())
await runtime.add_subscription(TypeSubscription(topic_type='default', agent_type='my_agent')) Defensive patterns
Strategy: validation
Validate before calling
from autogen_core import AgentId
async def can_materialize(runtime, agent_id: AgentId) -> bool:
factory = getattr(runtime, '_agent_factories', {}).get(agent_id.type)
return factory is not None and 'not registered' not in getattr(factory, '__doc__', '') Try / catch
try:
await runtime.send_message(msg, AgentId(agent_type, key))
except RuntimeError as e:
if 'Agent factory was invoked' in str(e):
raise RuntimeError(f'{agent_type} is instance-registered; key {key!r} unknown — check subscriptions') from e
raise Prevention
- Prefer register_factory for any type that receives topic-fanout messages
- Map instance-registered types only to subscriptions targeting the exact registered key
- Audit that instance types are not subscribed to DefaultTopicId
- Register instances for every key the subscription can deliver to
When it happens
Trigger: An agent type registered via register_agent_instance is subscribed to a topic (often the DefaultTopicId via implicit class subscription) so the host routes messages keyed by source/key rather than by the registered instance key; the worker then calls _get_agent for an unknown AgentId, finds only the placeholder factory, and invoking it raises. Typical when skip_class_subscriptions=True suppresses the instance mapping, or when a TypeSubscription matches messages published by many keys to a single-instance type.
Common situations: Registering one agent instance of a type but publishing to a topic that fans out to multiple agent keys; using register_agent_instance together with default class subscriptions on DefaultTopicId; copying single-agent examples into multi-agent topic topologies; subscriptions added on the host side that the worker is unaware of.
Related errors
- Agent with name {agent_id.type} not found.
- Target is null.
- Message must have a topic to be published.
- Handoff message target does not match agent name: {messages[
- Invalid next speaker: {next_speaker} from the ledger, partic
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/1c67938ad2837db5.
Report an issue: GitHub.