microsoft/semantic-kernel · error · InvalidOperationException

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

Error message

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

What it means

HandleMessageAsync looks up the invocable function name in the _functions dictionary. If the function name from _inputs (which should mirror _functions) is not found in _functions, this InvalidOperationException is thrown. This indicates an inconsistency between the input-channel map and the loaded kernel functions.

Source

Thrown at dotnet/src/Experimental/Process.Runtime.Dapr/Actors/StepActor.cs:298

        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?.LogInformation("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?").Log(this._logger);

        this._logger?.LogInformation("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 InvalidOperationException($"Function {targetFunction} not found in plugin {this.Name}").Log(this._logger);
        }

        // 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
        {
            this?._logger?.LogInformation("Invoking function {FunctionName} with arguments {Arguments}", targetFunction, arguments);
            FunctionResult invokeResult = await this.InvokeFunction(function, this._kernel, arguments).ConfigureAwait(false);

            this?.Logger?.LogInformation("Function {FunctionName} returned {Result}", targetFunction, invokeResult);

            // Persist the state after the function has been executed
            var stateJson = JsonSerializer.Serialize(this._stepState, this._stepStateType!);
            await this.StateManager.SetStateAsync(ActorStateKeys.StepStateJson, stateJson).ConfigureAwait(false);
            await this.StateManager.SaveStateAsync().ConfigureAwait(false);

            await this.EmitEventAsync(
                ProcessEvent.Create(

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Verify that GenerateInitialInputs (or its override) only returns function names that exist in the _functions dictionary.
  2. If overriding GenerateInitialInputs or AssignStepFunctionParameterValues in a subclass, ensure consistency between input keys and loaded functions.
  3. Inspect the step's [KernelFunction] methods and the KernelPlugin created from the step instance to confirm all expected functions are loaded.
Defensive patterns

Strategy: validation

Validate before calling

// This is an internal consistency error. Verify that GenerateInitialInputs produces keys
// that match the loaded kernel functions:
var plugin = KernelPluginFactory.CreateFromObject(stepInstance);
var functionNames = plugin.Select(f => f.Name).ToHashSet();
var inputKeys = stepInstance.GenerateInitialInputs().Keys.ToHashSet();
if (!inputKeys.IsSubsetOf(functionNames))
{
    throw new InvalidOperationException("Input channel keys do not match loaded functions.");
}

Try / catch

try
{
    await stepActor.ProcessIncomingMessagesAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not found in plugin"))
{
    logger.LogError("Function name inconsistency between input channels and loaded kernel functions. This is likely an internal bug or a subclass override issue.");
}

Prevention

When it happens

Trigger: The _inputs dictionary contains a key for a function that does not exist in _functions. Since GenerateInitialInputs derives _inputs from _functions via FindInputChannels, this mismatch should not occur under normal operation — it points to a corrupted state or a race condition during activation.

Common situations: A bug in FindInputChannels or GenerateInitialInputs that creates input entries for functions not in the plugin. Concurrent modification of _inputs or _functions during message processing. A subclass override of GenerateInitialInputs that introduces inconsistent keys.

Related errors


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