microsoft/semantic-kernel · error · ValueError
Agent with type {type} already exists.
Error message
Agent with type {type} already exists. What it means
register_factory checks if the agent type string already exists in _agent_factories before registering. If a factory was already registered for that type, it raises ValueError. This prevents accidental shadowing of one factory by another.
Source
Thrown at python/semantic_kernel/agents/runtime/in_process/in_process_runtime.py:741
return await (await self._get_agent(agent)).save_state()
async def agent_load_state(self, agent: AgentId, state: Mapping[str, Any]) -> None:
"""Load the state of a single agent."""
await (await self._get_agent(agent)).load_state(state)
async def register_factory(
self,
type: str | AgentType,
agent_factory: Callable[[], T | Awaitable[T]],
*,
expected_class: type[T] | None = None,
) -> AgentType:
"""Register a factory for creating agents."""
if isinstance(type, str):
type = CoreAgentType(type)
if type.type in self._agent_factories:
raise ValueError(f"Agent with type {type} already exists.")
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
return type
async def _invoke_agent_factory(View on GitHub (pinned to c028a0c7dc)
Solutions
- Create a new InProcessRuntime instance for each test or session rather than re-registering on an existing one.
- Check if the type is already registered before calling register_factory (though the runtime does not expose a public 'is_registered' check, you can track this in your own code).
- Call runtime.stop() and create a fresh runtime if you need to re-register.
Example fix
# before
await runtime.register_factory('my_agent', factory1)
await runtime.register_factory('my_agent', factory2) # raises
# after
await runtime.register_factory('my_agent', factory1)
# To change factory, create a new runtime:
runtime = InProcessRuntime()
await runtime.register_factory('my_agent', factory2) Defensive patterns
Strategy: validation
Validate before calling
# Track registered types in your own code
registered_types: set[str] = set()
async def safe_register_factory(runtime, type_name, factory, expected_class=None):
if type_name in registered_types:
return # already registered, skip
await runtime.register_factory(type_name, factory, expected_class=expected_class)
registered_types.add(type_name) Type guard
null
Try / catch
try:
await runtime.register_factory(type_name, factory)
except ValueError:
pass # already registered — acceptable in idempotent setup Prevention
- Create a fresh InProcessRuntime per test or per session.
- Make registration idempotent by catching ValueError or tracking types yourself.
- Avoid module-level registration that can run twice on reload.
When it happens
Trigger: Calling register_factory('MyAgent', factory1) then register_factory('MyAgent', factory2) without the runtime being reset. Also occurs when the same registration code runs twice (e.g. in a test that doesn't tear down, or a module-level registration executed on import in a reload).
Common situations: Test suites that register factories in setUp without creating a fresh runtime. Application code that registers on every request or reconnect. Importing a module that performs registration at module level, twice (e.g. via test reload).
Related errors
- Factory registered using the wrong type.
- Agent factory must take 0 or 2 arguments.
- Agent with name {agent_id.type} not found.
- Agent with name {id.type} not found.
- Subscription already exists
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/bf1bbac8caf341eb.
Report an issue: GitHub.