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
- Ensure every method referenced by input channels is annotated with [KernelFunction] and is public instance.
- Verify the step type is correctly instantiated and that KernelPluginFactory.CreateFromObject discovers all expected functions.
- 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
- Annotate every callable method on step classes with [KernelFunction].
- Ensure methods are public instance (not static or private) so KernelPluginFactory discovers them.
- Validate at startup that all expected functions exist in the generated plugin.
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
- A message targeting function '{message.FunctionName}' has re
- External message channel not configured for step with topic
- External message channel not configured for step
- The process must have an Id set
- Attempt to build a workflow node from step with no Id
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/58601a804ff068fc.
Report an issue: GitHub.