microsoft/semantic-kernel · error · KernelException

The ActivateAsync method failed to complete.

Error message

The ActivateAsync method failed to complete.

What it means

Thrown by LocalStep.InitializeStepAsync when the reflection-invoked ActivateAsync method returns null instead of a ValueTask. After locating the method via GetMethod, the code invokes it and casts the result to ValueTask?; a null result means the method's actual return type is not ValueTask (e.g., it returns void, Task, or null).

Source

Thrown at dotnet/src/Experimental/Process.LocalRuntime/LocalStep.cs:318

        // Activate the step with user-defined state if needed
        Type stateType = this._stepInfo.InnerStepType.ExtractStateType(out Type? userStateType, this._logger);
        KernelProcessStepState stateObject = this._stepInfo.State;
        stateObject.InitializeUserState(stateType, userStateType);

        if (stateObject is null)
        {
            throw new KernelException("The state object for the KernelProcessStep could not be created.").Log(this._logger);
        }

        MethodInfo methodInfo =
            this._stepInfo.InnerStepType.GetMethod(nameof(KernelProcessStep.ActivateAsync), [stateType]) ??
            throw new KernelException("The ActivateAsync method for the KernelProcessStep could not be found.").Log(this._logger);

        this._stepState = stateObject;

        ValueTask activateTask =
            (ValueTask?)methodInfo.Invoke(this._stepInstance, [stateObject]) ??
            throw new KernelException("The ActivateAsync method failed to complete.").Log(this._logger);

        await this._stepInstance.ActivateAsync(stateObject).ConfigureAwait(false);
        await activateTask.ConfigureAwait(false);
    }

    /// <summary>
    /// Deinitializes the step
    /// </summary>
    public virtual Task DeinitializeStepAsync()
    {
        this._logger.LogInformation("Step {Name} has deinitialized", this.Name);
        return Task.CompletedTask;
    }

    /// <summary>
    /// Invokes the provides function with the provided kernel and arguments.
    /// </summary>
    /// <param name="function">The function to invoke.</param>

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure ActivateAsync returns ValueTask, matching the KernelProcessStep contract.
  2. If overriding in a generic step, use 'public override ValueTask ActivateAsync(TState state)'.
  3. Avoid declaring ActivateAsync with a non-ValueTask return type.

Example fix

// before - returns Task
class MyStep : KernelProcessStep<MyState> {
    public override Task ActivateAsync(MyState state) { ... }
}
// after - returns ValueTask
class MyStep : KernelProcessStep<MyState> {
    public override ValueTask ActivateAsync(MyState state) { ... }
}
Defensive patterns

Strategy: type-guard

Type guard

// Verify ActivateAsync returns ValueTask
var stateType = typeof(MyStep).ExtractStateType(out _, logger);
var method = typeof(MyStep).GetMethod(nameof(KernelProcessStep.ActivateAsync), [stateType]);
if (method?.ReturnType != typeof(ValueTask)) { /* return type mismatch */ }

Prevention

When it happens

Trigger: The step type declares an ActivateAsync method with the right parameter type but a different return type than ValueTask, so the cast to ValueTask? produces null and the null-coalescing throw fires.

Common situations: A custom step where ActivateAsync returns Task or void instead of ValueTask; the method is a 'new' slot or hides the base method; signature drift between the declared override and what reflection binds to.

Related errors


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