microsoft/semantic-kernel · error · KernelException

The initial state provided for step {this.Name} is not of th

Error message

The initial state provided for step {this.Name} is not of the correct type. The expected type is {userStateType.Name}.

What it means

Thrown by ProcessStepBuilder.BuildStep during JSON deserialization of a stateful step's initial state. The step derives from KernelProcessStep<TState>, and the state metadata supplied at build time is a JsonElement that cannot be deserialized into the user-defined state type TState. The framework catches the inner JsonException and rethrows this KernelException to surface a clear, type-named failure.

Source

Thrown at dotnet/src/Experimental/Process.Core/ProcessStepBuilder.cs:318

        if (this._stepType.TryGetSubtypeOfStatefulStep(out Type? genericStepType) && genericStepType is not null)
        {
            // The step is a subclass of KernelProcessStep<>, so we need to extract the generic type argument
            // and create an instance of the corresponding KernelProcessStepState<>.
            var userStateType = genericStepType.GetGenericArguments()[0];
            Verify.NotNull(userStateType);

            var stateType = typeof(KernelProcessStepState<>).MakeGenericType(userStateType);
            Verify.NotNull(stateType);

            if (stateMetadata != null && stateMetadata.State != null && stateMetadata.State is JsonElement jsonState)
            {
                try
                {
                    this._initialState = jsonState.Deserialize(userStateType);
                }
                catch (JsonException)
                {
                    throw new KernelException($"The initial state provided for step {this.Name} is not of the correct type. The expected type is {userStateType.Name}.");
                }
            }

            // If the step has a user-defined state then we need to validate that the initial state is of the correct type.
            if (this._initialState is not null && this._initialState.GetType() != userStateType)
            {
                throw new KernelException($"The initial state provided for step {this.Name} is not of the correct type. The expected type is {userStateType.Name}.");
            }

            var initialState = this._initialState ?? Activator.CreateInstance(userStateType);
            stateObject = (KernelProcessStepState?)Activator.CreateInstance(stateType, this.Name, stepMetadataAttributes.Version, this.Id);
            stateType.GetProperty(nameof(KernelProcessStepState<object>.State))?.SetValue(stateObject, initialState);
        }
        else
        {
            // The step is a KernelProcessStep with no user-defined state, so we can use the base KernelProcessStepState.
            stateObject = new KernelProcessStepState(this.Name, stepMetadataAttributes.Version, this.Id);
        }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect the expected type named in the message and reconcile your state JSON so every property matches the TState POCO (names, types, nullability).
  2. Deserialize the same JsonElement with JsonSerializer.Deserialize<TState>(jsonState) in a scratch test to capture the real JsonException with line/byte/path detail.
  3. Ensure the JsonSerializerOptions used to produce the JsonElement (e.g. property naming policy, case sensitivity) match what TState expects.
  4. If the state legitimately belongs to a different step, route it to the correct step or update the step's generic state argument.

Example fix

// before: state JSON has { "count": 5 } but TState expects an int named "Counter"
stepBuilder.BuildStep(pb, stateMetadata);

// after: align JSON property name to TState
// { "Counter": 5 }
stepBuilder.BuildStep(pb, stateMetadata);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the state JsonElement round-trips into TState before building
bool CanDeserializeState<TState>(JsonElement el, JsonSerializerOptions opt)
{
    try { el.Deserialize<TState>(opt); return true; }
    catch (JsonException) { return false; }
}

Type guard

bool IsStateForStep<TState>(object state) => state is JsonElement el && CanDeserializeState<TState>(el, JsonSerializerOptions.Default);

Try / catch

try { builder.Build(); }
catch (KernelException ex) when (ex.Message.Contains("is not of the correct type"))
{
    // log expectedType, re-serialize the supplied JsonElement for comparison
}

Prevention

When it happens

Trigger: Calling Build() on a ProcessBuilder whose stateful step was given KernelProcessStepStateMetadata with a State JsonElement whose shape does not match the declared user state type (missing properties, wrong property types, malformed JSON, or a state payload belonging to a different step type).

Common situations: Loading a process from serialized state where the schema evolved (renamed/removed TState fields), pasting state JSON from another step, or supplying a JsonElement produced by a different JsonSerializerOptions that yields incompatible tokens.

Related errors


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