microsoft/semantic-kernel · error · KernelException

The step has no functions.

Error message

The step {this.Name} has no functions.

What it means

Thrown by ProcessStepBuilder.ResolveFunctionName (a private method called during target resolution) when FunctionsDict is empty — the step has no kernel functions at all. Resolution requires at least one function to infer or select from.

Solutions

  1. Ensure the step class has at least one method decorated with [KernelFunction("name")].
  2. Verify the step type is the correct concrete class, not an abstract base or state-only class.
  3. Check that kernel function methods are public and properly decorated if using a dynamic loading scenario.

Example fix

// before — step has no kernel functions
public class EmptyStep : KernelProcessStep { }
process.AddStepFromType<EmptyStep>();
// any edge targeting EmptyStep throws

// after — add a kernel function
public class MyStep : KernelProcessStep
{
    [KernelFunction]
    public void DoWork() { }
}
process.AddStepFromType<MyStep>();
Defensive patterns

Strategy: validation

Validate before calling

if (step.FunctionsDict.Count == 0)
    throw new InvalidOperationException(
        $"Step '{step.Name}' has no kernel functions. Add at least one [KernelFunction] method.");

// proceed with edge targeting

Type guard

bool HasKernelFunctions(ProcessStepBuilder step) => step.FunctionsDict.Count > 0;

Prevention

When it happens

Trigger: Targeting a step that has zero [KernelFunction] methods, then attempting to resolve a function name without specifying one (relying on auto-resolution). Also triggered when a step type is loaded but its function metadata is empty.

Common situations: Using a step class with no [KernelFunction]-decorated methods; the step type was loaded dynamically but reflection found no kernel functions (e.g. methods are private or not decorated); using an abstract base class or a state-only step as a process step; version change where functions were removed.

Related errors


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

Appendix: source

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

        if (this.IncomingEdgeGroups.ContainsKey(edgeGroup.GroupId))
        {
            return;
        }

        // Register the group by GroupId.
        this.IncomingEdgeGroups[edgeGroup.GroupId] = edgeGroup;
    }

    /// <summary>
    /// Resolves the function name for the step.
    /// </summary>
    /// <returns></returns>
    /// <exception cref="KernelException"></exception>
    private string ResolveFunctionName()
    {
        if (this.FunctionsDict.Count == 0)
        {
            throw new KernelException($"The step {this.Name} has no functions.");
        }
        else if (this.FunctionsDict.Count > 1)
        {
            throw new KernelException($"The step {this.Name} has more than one function, so a function name must be provided.");
        }

        return this.FunctionsDict.Keys.First();
    }

    /// <summary>
    /// Links the output of the current step to the an input of another step via the specified event type.
    /// </summary>
    /// <param name="eventId">The Id of the event.</param>
    /// <param name="edgeBuilder">The targeted function.</param>
    internal virtual void LinkTo(string eventId, ProcessStepEdgeBuilder edgeBuilder)
    {
        if (!this.Edges.TryGetValue(eventId, out List<ProcessStepEdgeBuilder>? edges) || edges == null)
        {

View on GitHub (pinned to c028a0c7dc)