{"record":{"id":"a44e7a6cd15f8321","repo":"microsoft/semantic-kernel","slug":"aicontextproviders-with-aifunctions-are-not-suppor-a44e7a","errorCode":null,"errorMessage":"AIContextProviders with AIFunctions are not supported when Agent UseImmutableKernel setting is false.","messagePattern":"AIContextProviders with AIFunctions are not supported when Agent UseImmutableKernel setting is false\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Agents/OpenAI/OpenAIResponseAgent.cs","lineNumber":178,"sourceCode":"        return await this.EnsureThreadExistsWithMessagesAsync(messages, thread, () => new ChatHistoryAgentThread(), cancellationToken).ConfigureAwait(false);\n    }\n\n    private async Task<OpenAIResponseAgentInvokeOptions> FinalizeInvokeOptionsAsync(ICollection<ChatMessageContent> messages, AgentInvokeOptions? options, AgentThread agentThread, CancellationToken cancellationToken)\n    {\n        Kernel kernel = this.GetKernel(options);\n#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.\n        if (this.UseImmutableKernel)\n        {\n            kernel = kernel.Clone();\n        }\n\n        // Get the AIContextProviders contributions to the kernel.\n        AIContext providersContext = await agentThread.AIContextProviders.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);\n\n        // Check for compatibility AIContextProviders and the UseImmutableKernel setting.\n        if (providersContext.AIFunctions is { Count: > 0 } && !this.UseImmutableKernel)\n        {\n            throw new InvalidOperationException(\"AIContextProviders with AIFunctions are not supported when Agent UseImmutableKernel setting is false.\");\n        }\n\n        kernel.Plugins.AddFromAIContext(providersContext, \"Tools\");\n#pragma warning restore SKEXP0130 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.\n\n        string mergedAdditionalInstructions = FormatAdditionalInstructions(providersContext, options);\n        OpenAIResponseAgentInvokeOptions extensionsContextOptions =\n            options is null ?\n                new()\n                {\n                    AdditionalInstructions = mergedAdditionalInstructions,\n                    Kernel = kernel,\n                } :\n                new(options)\n                {\n                    AdditionalInstructions = mergedAdditionalInstructions,\n                    Kernel = kernel,\n                };","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Agents/OpenAI/OpenAIResponseAgent.cs#L160-L196","documentation":"Thrown by FinalizeInvokeOptionsAsync when AIContextProviders contribute one or more AIFunctions (tools) but the agent's UseImmutableKernel is false. With UseImmutableKernel=false (the default, Agent.cs:79) the kernel is shared, and the code would add the provider's tools as plugins directly to that shared kernel — polluting it for every other caller. The library refuses rather than silently mutating shared state. With UseImmutableKernel=true the kernel is cloned (kernel.Clone()) first, so plugin additions are isolated.","triggerScenarios":"Configuring an OpenAIResponseAgent whose AgentThread has AIContextProviders that return AIFunctions, and invoking it while agent.UseImmutableKernel is left at its default of false.","commonSituations":"Adding a tool/function provider to a thread and forgetting to enable immutable kernel; copying a working config from a single-agent setup into a shared-kernel service.","solutions":["Set responseAgent.UseImmutableKernel = true (this clones the kernel so provider tools can be added safely).","Alternatively, remove AIFunctions from the AIContextProviders if you must keep the shared mutable kernel.","Set the property at construction time before the first invoke so FinalizeInvokeOptionsAsync sees it."],"exampleFix":"// before\nvar agent = new OpenAIResponseAgent(client);\nthread.AIContextProviders.Add(providerWithFunctions);\nawait agent.InvokeAsync(messages, thread); // throws InvalidOperationException\n\n// after\nvar agent = new OpenAIResponseAgent(client) { UseImmutableKernel = true };\nawait agent.InvokeAsync(messages, thread);","handlingStrategy":"validation","validationCode":"// Enable immutable kernel before invoking when providers carry functions\nif (thread.AIContextProviders.Any(p => p is { } /* exposes AIFunctions */))\n{\n    responseAgent.UseImmutableKernel = true;\n}\nawait responseAgent.InvokeAsync(messages, thread);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set UseImmutableKernel = true whenever AIContextProviders contribute AIFunctions.","Decide kernel mutability policy at construction, before the first invoke.","If you must share a mutable kernel, keep providers free of AIFunctions."],"tags":["kernel","plugins","configuration","responses-api","agents"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}