microsoft/semantic-kernel · error · ArgumentException

Function {targetFunction} not found in plugin {this.Name}

Error message

Function {targetFunction} not found in plugin {this.Name}

What it means

Thrown as ArgumentException by LocalStep.HandleMessageAsync when the targetFunction (determined to be invocable) is not found in the _functions dictionary. The _functions dictionary is populated from the step's KernelPlugin during InitializeStepAsync; the function being invocable (its input channels are satisfied) but absent from _functions means the input channel mapping references a function that the plugin does not expose.

Source

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

        if (invocableFunctions.Count == 0)
        {
            string missingKeysLog() => string.Join(", ", missingKeys.Select(k => $"{k.Key}: {string.Join(", ", k.Value?.Where(v => v.Value == null).Select(v => v.Key) ?? [])}"));
            this._logger.LogDebug("No invocable functions, missing keys: {MissingKeys}", missingKeysLog());
            return;
        }

        // A message can only target one function and should not result in a different function being invoked.
        var targetFunction = invocableFunctions.FirstOrDefault((name) => name == message.FunctionName) ??
            throw new InvalidOperationException($"A message targeting function '{message.FunctionName}' has resulted in a function named '{invocableFunctions.First()}' becoming invocable. Are the function names configured correctly?");

        this._logger.LogDebug("Step with Id `{StepId}` received all required input for function [{TargetFunction}] and is executing.", this.Name, targetFunction);

        // Concat all the inputs and run the function
        KernelArguments arguments = new(this._inputs[targetFunction]!);
        if (!this._functions.TryGetValue(targetFunction, out KernelFunction? function) || function == null)
        {
            throw new ArgumentException($"Function {targetFunction} not found in plugin {this.Name}");
        }

        // Invoke the function, catching all exceptions that it may throw, and then post the appropriate event.
#pragma warning disable CA1031 // Do not catch general exception types
        try
        {
            // TODO: Process edges for the OnStepEnter event: This feels like a good use for filters in the non-declarative version

            FunctionResult invokeResult = await this.InvokeFunction(function, this._kernel, arguments).ConfigureAwait(false);
            this.EmitEvent(
                ProcessEvent.Create(
                    invokeResult.GetValue<object>(),
                    this._eventNamespace,
                    sourceId: $"{targetFunction}.OnResult",
                    eventVisibility: KernelProcessEventVisibility.Public));

            // TODO: Process edges for the OnStepExit event: This feels like a good use for filters in the non-declarative version
        }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure every method referenced by input channels is annotated with [KernelFunction] and is public instance.
  2. Verify the step type is correctly instantiated and that KernelPluginFactory.CreateFromObject discovers all expected functions.
  3. Check for method overloads that may confuse plugin discovery; ensure the method signature matches what input channels expect.

Example fix

// before - method lacks [KernelFunction]
public void DoWork(string input) { }
// after - annotate with [KernelFunction]
[KernelFunction]
public void DoWork(string input) { }
Defensive patterns

Strategy: type-guard

Type guard

// Verify the step type has KernelFunction methods matching expected function names
var pluginFunctions = KernelPluginFactory.CreateFromObject(stepInstance)
    .Select(f => f.Name).ToHashSet();
foreach (var expectedFn in expectedFunctionNames)
{
    if (!pluginFunctions.Contains(expectedFn)) { /* warn: function not found in plugin */ }
}

Prevention

When it happens

Trigger: The step's input channels (built from FindInputChannels) recognize a function name, but KernelPluginFactory.CreateFromObject did not register that function name. The invocableFunctions list derives from _inputs keys, while _functions derives from the plugin; a mismatch between the two causes the lookup to fail.

Common situations: The step type has input channel attributes referencing a method that is not annotated with [KernelFunction]; the method is private or static so the plugin factory skips it; a version mismatch where input channel discovery and plugin discovery use different rules.

Related errors


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