microsoft/semantic-kernel · error · ValueError

Agent factory must take 0 or 2 arguments.

Error message

Agent factory must take 0 or 2 arguments.

What it means

_invoke_agent_factory inspects the factory's signature and expects either 0 parameters (modern) or 2 parameters (deprecated runtime+agent_id). If the factory has any other arity (1, 3+), ValueError is raised. The two-arg form is deprecated and emits a DeprecationWarning.

Source

Thrown at python/semantic_kernel/agents/runtime/in_process/in_process_runtime.py:778

        self,
        agent_factory: Callable[[], T | Awaitable[T]] | Callable[[CoreRuntime, AgentId], T | Awaitable[T]],
        agent_id: AgentId,
    ) -> T:
        with AgentInstantiationContext.populate_context((self, agent_id)):
            try:
                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,
                    )
                    factory_two = cast(Callable[[CoreRuntime, AgentId], T], agent_factory)
                    agent = factory_two(self, agent_id)
                else:
                    raise ValueError("Agent factory must take 0 or 2 arguments.")

                if inspect.isawaitable(agent):
                    return cast(T, await agent)

                return agent

            except BaseException as e:
                event_logger.info(
                    AgentConstructionExceptionEvent(
                        agent_id=agent_id,
                        exception=e,
                    )
                )
                logger.error(f"Error constructing agent {agent_id}", exc_info=True)
                raise

    async def _get_agent(self, agent_id: AgentId) -> Agent:
        if agent_id in self._instantiated_agents:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Use a 0-argument factory (preferred): capture any needed config via closure.
  2. If you need runtime/agent_id access, use AgentInstantiationContext.current_runtime() and current_agent_id() inside a 0-arg factory instead of the deprecated 2-arg form.
  3. If using a bound method, be aware that self is not counted by inspect.signature on bound methods — but on unbound methods it is.

Example fix

# before
async def factory(config):
    return MyAgent(config)
await runtime.register_factory('my_agent', functools.partial(factory, my_config))  # 1 arg raises

# after
def factory():
    return MyAgent(my_config)
await runtime.register_factory('my_agent', factory)  # 0 args, config via closure
Defensive patterns

Strategy: validation

Validate before calling

import inspect

def validate_factory_arity(factory):
    params = inspect.signature(factory).parameters
    n = len(params)
    if n not in (0, 2):
        raise ValueError(f'Factory must take 0 or 2 arguments, got {n}')
    return factory

validate_factory_arity(my_factory)
await runtime.register_factory('my_agent', my_factory)

Type guard

import inspect

def is_valid_factory(factory) -> bool:
    n = len(inspect.signature(factory).parameters)
    return n in (0, 2)

Try / catch

null

Prevention

When it happens

Trigger: Registering a factory function with 1 argument (e.g. def factory(runtime) or 3+ arguments. The runtime only supports 0-arg or 2-arg factories.

Common situations: A developer writes a factory that takes a runtime or configuration argument, not realizing the API only supports 0 or 2 args. Migrating from a closure-based factory to a method-based one changes the visible arity (self becomes param 1).

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/96dc1aa55c235ca9. Report an issue: GitHub.