microsoft/semantic-kernel · error · InvalidOperationException
API key was not specified.
Error message
API key was not specified.
What it means
ModelConnectionExtensions.GetApiKeyCredential reads the 'api_key' key from the connection's ExtensionData and wraps it in an ApiKeyCredential. If the key is absent or null it throws InvalidOperationException, because no credential can be produced.
Source
Thrown at dotnet/src/Agents/OpenAI/Extensions/ModelConnectionExtensions.cs:37
internal static Uri? TryGetEndpoint(this ModelConnection connection)
{
Verify.NotNull(connection);
return connection.ExtensionData.TryGetValue("endpoint", out var value) && value is not null && value is string endpoint
? new Uri(endpoint)
: null;
}
/// <summary>
/// Gets the API key property as an <see cref="ApiKeyCredential"/> from the specified <see cref="ModelConnection"/>.
/// </summary>
/// <param name="connection">Model connection</param>
internal static ApiKeyCredential GetApiKeyCredential(this ModelConnection connection)
{
Verify.NotNull(connection);
return !connection.ExtensionData.TryGetValue("api_key", out var apiKey) || apiKey is null
? throw new InvalidOperationException("API key was not specified.")
: new ApiKeyCredential(apiKey.ToString()!);
}
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure the connection ExtensionData contains a non-null 'api_key' entry (exact lowercase key).
- Load the key from configuration/environment and inject it into ExtensionData at startup.
- Verify secret loading (e.g., dotnet user-secrets, env vars) actually populated the value.
Example fix
// before connection.ExtensionData["apiKey"] = key; // after connection.ExtensionData["api_key"] = key;
Defensive patterns
Strategy: validation
Validate before calling
if (!connection.ExtensionData.TryGetValue("api_key", out var key) || key is null)
throw new InvalidOperationException("ModelConnection is missing a non-null 'api_key'."); Type guard
static bool HasApiKey(ModelConnection c) =>
c.ExtensionData.TryGetValue("api_key", out var v) && v is not null; Try / catch
try { var cred = connection.GetApiKeyCredential(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("API key was not specified")) {
connection.ExtensionData["api_key"] = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
} Prevention
- Use the exact lowercase 'api_key' key in ExtensionData.
- Load keys from a secret manager and inject them at startup.
- Add a configuration validator that checks for the api_key entry.
When it happens
Trigger: Calling GetApiKeyCredential on a ModelConnection whose ExtensionData has no 'api_key' entry, or the entry's value is null.
Common situations: Agent-definition YAML uses a different key name (e.g., 'apiKey', 'token'); api_key expected from an environment variable that was not injected; secret redaction stripped the value.
Related errors
- Please provide an api_key
- OPENAI_API_KEY is not set.
- OPENAI_API_KEY is not set.
- OPENAI_API_KEY is not set.
- OPENAI_API_KEY is not set.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/3a26634b79ca6f17.
Report an issue: GitHub.