microsoft/semantic-kernel · error · ArgumentException

AgentDefinition.Id cannot be null or empty.

Error message

AgentDefinition.Id cannot be null or empty.

What it means

Thrown by ProcessBuilder.AddStepFromAgentProxy<TProcessState> when agentDefinition.Id is null, empty, or whitespace. The proxy agent variant requires Id because it constructs a KernelProcessStateResolver that evaluates agentDefinition.Id as a JMESPath expression at runtime to resolve the agent ID dynamically.

Source

Thrown at dotnet/src/Experimental/Process.Core/ProcessBuilder.cs:303

    }

    /// <summary>
    /// Adds a step to the process from a declarative agent.
    /// </summary>
    /// <param name="agentDefinition">The <see cref="AgentDefinition"/></param>
    /// <param name="threadName">Specifies the thread reference to be used by the agent. If not provided, the agent will create a new thread for each invocation.</param>
    /// <param name="stepId">Id of the step. If not provided, the Id will come from the agent Id.</param>
    /// <param name="humanInLoopMode">Specifies the human-in-the-loop mode for the agent. If not provided, the default is <see cref="HITLMode.Never"/>.</param>
    /// <param name="aliases"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public ProcessAgentBuilder<TProcessState> AddStepFromAgentProxy<TProcessState>(AgentDefinition agentDefinition, string? threadName = null, string? stepId = null, HITLMode humanInLoopMode = HITLMode.Never, IReadOnlyList<string>? aliases = null) where TProcessState : class, new()
    {
        Verify.NotNull(agentDefinition, nameof(agentDefinition));

        if (string.IsNullOrWhiteSpace(agentDefinition.Id))
        {
            throw new ArgumentException("AgentDefinition.Id cannot be null or empty.", nameof(agentDefinition));
        }

        if (string.IsNullOrWhiteSpace(agentDefinition.Name))
        {
            throw new ArgumentException("AgentDefinition.Name cannot be null or empty.", nameof(agentDefinition));
        }

        if (string.IsNullOrWhiteSpace(threadName))
        {
            // No thread name was specified so add a new thread for the agent.
            this.AddThread(agentDefinition.Name, KernelProcessThreadLifetime.Scoped);
            threadName = agentDefinition.Name;
        }

        KernelProcessStateResolver<string?> agentIdResolver = new((s) =>
        {
            StateResolverContentWrapper wrapper = new() { State = s };
            var result = JMESPathConditionEvaluator.EvaluateToString(wrapper, agentDefinition.Id);

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Set agentDefinition.Id to a non-empty string (can be a JMESPath expression or literal agent ID) before calling AddStepFromAgentProxy.
  2. If you do not need dynamic agent ID resolution, use AddStepFromAgent instead, which does not require Id.
  3. Validate that the agent definition file includes a non-empty 'id' field when using the proxy pattern.

Example fix

// before
var def = new AgentDefinition { Name = "MyAgent" }; // Id is null
process.AddStepFromAgentProxy<MyState>(def); // throws

// after
var def = new AgentDefinition { Id = "$.agentId", Name = "MyAgent" };
process.AddStepFromAgentProxy<MyState>(def);
Defensive patterns

Strategy: validation

Validate before calling

public static void EnsureAgentIdAndName(AgentDefinition def)
{
    if (string.IsNullOrWhiteSpace(def.Id))
    {
        throw new ArgumentException("AgentDefinition.Id is required for proxy agents.", nameof(def));
    }
    if (string.IsNullOrWhiteSpace(def.Name))
    {
        throw new ArgumentException("AgentDefinition.Name is required for proxy agents.", nameof(def));
    }
}

Type guard

public static bool HasAgentIdAndName(AgentDefinition def)
    => !string.IsNullOrWhiteSpace(def.Id) && !string.IsNullOrWhiteSpace(def.Name);

Prevention

When it happens

Trigger: Calling AddStepFromAgentProxy<TProcessState> with an AgentDefinition whose Id is null or whitespace. This overload has stricter requirements than AddStepFromAgent — it needs both Id (checked first) and Name (checked second).

Common situations: Using the proxy agent flow (AddStepFromAgentProxy) with a definition file that has 'name' but no 'id'. Confusing AddStepFromAgent (requires Name only) with AddStepFromAgentProxy (requires both Id and Name). JMESPath expression in the Id field that evaluates to null at runtime (though this specific throw is for the string being null/empty before resolution).

Related errors


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