microsoft/autogen · error · ValueError

Agent with type {type} already exists.

Error message

Agent with type {type} already exists.

What it means

GrpcWorkerAgentRuntime.register_factory stores factories in a dict keyed by AgentType.type. If the key already exists it raises ValueError('Agent with type {type} already exists.') to prevent one factory from silently replacing another. The check is purely local to this worker process, independent of what other workers registered.

Source

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

        if self._host_connection is None:
            raise RuntimeError("Host connection is not set.")
        message = agent_worker_pb2.RegisterAgentTypeRequest(type=agent_type)
        _response: agent_worker_pb2.RegisterAgentTypeResponse = await self._host_connection.stub.RegisterAgent(
            message, metadata=self._host_connection.metadata
        )

    async def register_factory(
        self,
        type: str | AgentType,
        agent_factory: Callable[[], T | Awaitable[T]],
        *,
        expected_class: type[T] | None = None,
    ) -> AgentType:
        if isinstance(type, str):
            type = AgentType(type)

        if type.type in self._agent_factories:
            raise ValueError(f"Agent with type {type} already exists.")
        if self._host_connection is None:
            raise RuntimeError("Host connection is not set.")

        async def factory_wrapper() -> T:
            maybe_agent_instance = agent_factory()
            if inspect.isawaitable(maybe_agent_instance):
                agent_instance = await maybe_agent_instance
            else:
                agent_instance = maybe_agent_instance

            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)

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Guard or deduplicate registration: check the type is not already registered before calling register_factory
  2. Use unique type names per registration attempt (e.g. suffix with a run id) when re-registration is expected
  3. Restart the runtime/kernel between notebook or test runs so the in-memory factory map resets
  4. Restructure code so registration happens exactly once per process (register in a single setup function)

Example fix

# before
await runtime.register_factory(MyAgent, MyAgent)  # re-run cell -> ValueError

# after
if MyAgent not in [str(t) for t in registered]:
    await runtime.register_factory(MyAgent, MyAgent)
# or in notebooks: recreate the runtime / restart kernel before re-registering
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

try:
    await runtime.register_factory(MyAgent, MyAgent)
except ValueError as e:
    if 'already exists' in str(e):
        pass  # idempotent setup
    else:
        raise

Prevention

When it happens

Trigger: Calling register_factory twice with the same type string or AgentType on the same runtime instance; registering both a factory and an agent instance under the same type name; module-level registration code that re-executes (e.g. notebook re-runs, hot reload) against a still-alive runtime.

Common situations: Jupyter notebooks where a cell registering agents is re-run without restarting the kernel; test suites that build one runtime per session but reuse a module-level registry; copy-pasted registration code hitting the same type name; for-loops that accidentally register the same type on every iteration.

Related errors


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