microsoft/semantic-kernel · critical · InvalidOperationException
Please provide a valid OpenAI:ApiKey to run this sample. See
Error message
Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.
What it means
BaseSample.CreateKernelWithChatCompletionService builds config from user secrets + env vars and throws InvalidOperationException if OpenAI:ApiKey is absent. ChatModelId defaults to gpt-4o-mini if unset, but the API key is mandatory and has no default. The message is written to stderr before throwing.
Source
Thrown at dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/BaseSample.cs:90
}
/// <summary>
/// Creates an instance of <see cref="Kernel"/> with the OpenAI chat completion service registered.
/// </summary>
/// <returns>An instance of <see cref="Kernel"/>.</returns>
protected static Kernel CreateKernelWithChatCompletionService()
{
// Load and validate configuration
IConfigurationRoot config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables()
.Build();
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
const string Message = "Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.";
Console.Error.WriteLine(Message);
throw new InvalidOperationException(Message);
}
string modelId = config["OpenAI:ChatModelId"] ?? "gpt-4o-mini";
// Create kernel
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddOpenAIChatCompletion(modelId: modelId, apiKey: apiKey);
return kernelBuilder.Build();
}
/// <summary>
/// Displays the list of available MCP tools.
/// </summary>
/// <param name="tools">The list of the tools to display.</param>
protected static void DisplayTools(IList<McpClientTool> tools)
{
Console.WriteLine("Available MCP tools:");View on GitHub (pinned to c028a0c7dc)
Solutions
- dotnet user-secrets set OpenAI:ApiKey <your-key>.
- Or export OPENAI__ApiKey environment variable (use the __ hierarchy separator).
- Optionally set OpenAI:ChatModelId if you don't want the gpt-4o-mini default.
- Verify the user-secrets ID matches this project so secrets resolve.
Example fix
// before
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
const string Message = "Please provide a valid OpenAI:ApiKey to run this sample...";
Console.Error.WriteLine(Message);
throw new InvalidOperationException(Message);
}
// after (user secret)
// dotnet user-secrets set OpenAI:ApiKey sk-...
// dotnet user-secrets set OpenAI:ChatModelId gpt-4o Defensive patterns
Strategy: validation
Validate before calling
if (config["OpenAI:ApiKey"] is not { } apiKey)
throw new InvalidOperationException(
"Set OpenAI:ApiKey via user secrets or OPENAI__ApiKey env var."); Type guard
static bool HasOpenAiKey(IConfigurationRoot c) =>
!string.IsNullOrEmpty(c["OpenAI:ApiKey"]); Prevention
- Use dotnet user-secrets for the API key locally.
- Use OPENAI__ApiKey for CI/containers.
- Verify the user-secrets ID matches the project.
When it happens
Trigger: config["OpenAI:ApiKey"] is null after merging user secrets and environment variables.
Common situations: First run without user secrets, OPENAI_API_KEY env var not exported, or user-secrets ID bound to a different project.
Related errors
- Please provide a valid OpenAI:ApiKey to run this sample. See
- Configuration is not setup correctly.
- Please provide valid OpenAI configuration in appsettings.Dev
- OpenAI/Azure OpenAI configuration was not found.
- Configuration section '{section}' not found
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/98de126ba35dcc23.
Report an issue: GitHub.