microsoft/semantic-kernel · error · InvalidOperationException
A message targeting function '{message.FunctionName}' has re
Error message
A message targeting function '{message.FunctionName}' has resulted in a function named '{invocableFunctions.First()}' becoming invocable. Are the function names configured correctly? What it means
Thrown as InvalidOperationException by LocalStep.HandleMessageAsync when a message targets function X, but after assigning its inputs, a different function Y becomes fully invocable (all its required parameters are present). The framework enforces that a message for one function should not inadvertently complete the inputs of another function, which indicates the function names on edges do not match the step's actual function names.
Source
Thrown at dotnet/src/Experimental/Process.LocalRuntime/LocalStep.cs:225
}
// Add the message values to the inputs for the function
this.AssignStepFunctionParameterValues(message);
// If we're still waiting for inputs on all of our functions then don't do anything.
List<string> invocableFunctions = this._inputs.Where(i => i.Value != null && i.Value.All(v => v.Value != null)).Select(i => i.Key).ToList();
var missingKeys = this._inputs.Where(i => i.Value is null || i.Value.Any(v => v.Value is null));
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(View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure the FunctionName on every edge's KernelProcessFunctionTarget matches a [KernelFunction] method name on the target step exactly.
- Check for case-sensitivity issues in function names (e.g., 'process' vs 'Process').
- If two functions share parameter names, rename parameters or functions to avoid ambiguity in input channel resolution.
- Inspect the FindInputChannels logic to verify parameter-to-function mapping is unambiguous.
Example fix
// before - edge targets 'ProcessData' but step method is 'HandleData'
edge.OutputTarget = new KernelProcessFunctionTarget { FunctionName = "ProcessData" };
[KernelFunction] public void HandleData(string input) { }
// after - names match
edge.OutputTarget = new KernelProcessFunctionTarget { FunctionName = "HandleData" }; Defensive patterns
Strategy: validation
Validate before calling
// Validate that edge FunctionNames match actual KernelFunction method names on the step type
var functionNames = typeof(MyStep).GetMethods()
.Where(m => m.GetCustomAttribute<KernelFunctionAttribute>() != null)
.Select(m => m.Name).ToHashSet();
foreach (var edgeList in process.Edges.Values)
{
foreach (var edge in edgeList)
{
if (edge.OutputTarget is KernelProcessFunctionTarget ft && ft.StepId == myStepId)
{
if (!functionNames.Contains(ft.FunctionName)) { /* configuration error */ }
}
}
} Prevention
- Keep edge FunctionName values in sync with [KernelFunction] method names on step classes.
- Run a validation pass that reflects on step types and checks edge targets before StartAsync.
- Avoid giving two functions overlapping parameter names that could cause cross-invocation.
When it happens
Trigger: A message with FunctionName='A' is processed, and after AssignStepFunctionParameterValues merges the values, the invocableFunctions list contains only 'B' (not 'A'). The FirstOrDefault match on message.FunctionName fails, triggering the throw.
Common situations: An edge targets function 'ProcessData' but the step's method is named 'HandleData'; renaming a step's [KernelFunction] method without updating edge targets; case mismatch in function names; multiple functions sharing parameter names so that a message for one fills another's inputs.
Related errors
- Function {targetFunction} not found in plugin {this.Name}
- 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/63819431de865108.
Report an issue: GitHub.