microsoft/semantic-kernel · error · InvalidOperationException

AIContextProviders with AIFunctions are not supported when…

Error message

AIContextProviders with AIFunctions are not supported when Agent UseImmutableKernel setting is false.

What it means

In the streaming invoke path, if AIContextProviders contribute AIFunctions (Count > 0) while the agent's UseImmutableKernel is false, an InvalidOperationException is thrown. The functions would be added as plugins to a shared, mutable kernel, which is unsafe, so the combination is forbidden.

Solutions

  1. Set agent.UseImmutableKernel = true so the kernel is cloned per invocation before adding provider functions.
  2. Or remove the AIFunction-providing AIContextProviders if you must keep UseImmutableKernel false.
  3. Register the needed functions as normal kernel plugins instead of via AIContextProviders if cloning is undesirable.

Example fix

// before
var agent = new OpenAIAssistantAgent(...) { /* UseImmutableKernel default false */ };
thread.AIContextProviders.Add(providerWithFunctions);
// after
var agent = new OpenAIAssistantAgent(...) { UseImmutableKernel = true };
thread.AIContextProviders.Add(providerWithFunctions);
Defensive patterns

Strategy: validation

Validate before calling

bool providersHaveFunctions = thread.AIContextProviders
    .Any(p => p.GetFunctionsAsync(default).GetAwaiter().GetResult()?.Any() == true);
if (providersHaveFunctions && !agent.UseImmutableKernel)
    throw new InvalidOperationException("Enable UseImmutableKernel when providers contribute AIFunctions.");

Try / catch

try { await foreach (var r in agent.InvokeStreamingAsync(thread)) { } }
catch (InvalidOperationException ex) when (ex.Message.Contains("AIContextProviders with AIFunctions")) {
    agent.UseImmutableKernel = true;
}

Prevention

When it happens

Trigger: Configuring an OpenAIAssistantAgent with one or more AIContextProvider instances that register AIFunctions, while leaving UseImmutableKernel at its default (false), then invoking the agent.

Common situations: Adding function-providing context providers without enabling immutable kernel cloning; assuming plugins can safely mutate the shared kernel.

Related errors


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

Appendix: source

Thrown at dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs:155

        var internalOptions = options?.RunCreationOptions ?? (string.IsNullOrWhiteSpace(options?.AdditionalInstructions) ? null : new RunCreationOptions()
        {
            AdditionalInstructions = options?.AdditionalInstructions,
        });

        Kernel kernel = this.GetKernel(options);
#pragma warning disable SKEXP0110, SKEXP0130 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
        if (this.UseImmutableKernel)
        {
            kernel = kernel.Clone();
        }

        // Get the context contributions from the AIContextProviders.
        AIContext providersContext = await openAIAssistantAgentThread.AIContextProviders.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);

        // Check for compatibility AIContextProviders and the UseImmutableKernel setting.
        if (providersContext.AIFunctions is { Count: > 0 } && !this.UseImmutableKernel)
        {
            throw new InvalidOperationException("AIContextProviders with AIFunctions are not supported when Agent UseImmutableKernel setting is false.");
        }

        kernel.Plugins.AddFromAIContext(providersContext, "Tools");
#pragma warning restore SKEXP0110, SKEXP0130 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

        using var activity = ModelDiagnostics.StartAgentInvocationActivity(this.Id, this.GetDisplayName(), this.Description, kernel, messages);
        List<ChatMessageContent>? chatMessageContents = activity is not null ? [] : null;

        // Notify the thread of new messages and return them to the caller.
        await foreach (var result in InternalInvokeAsync().ConfigureAwait(false))
        {
            yield return new(result, openAIAssistantAgentThread);
            chatMessageContents?.Add(result);
        }

        activity?.SetAgentResponse(chatMessageContents);

        async IAsyncEnumerable<ChatMessageContent> InternalInvokeAsync()

View on GitHub (pinned to c028a0c7dc)