microsoft/semantic-kernel · error · ArgumentException
Unknown image detail level '{detailLevelString}'. Supported
Error message
Unknown image detail level '{detailLevelString}'. Supported values are 'Auto', 'Low' and 'High'. What it means
Thrown by GetChatImageDetailLevel when an image's metadata carries a 'ChatImageDetailLevel' string that is not Auto/Low/High (case-insensitive). The detail level controls OpenAI's vision processing budget; an unknown token cannot be sent, so an ArgumentException lists the valid values.
Source
Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs:955
};
}
private static ChatImageDetailLevel? GetChatImageDetailLevel(ImageContent imageContent)
{
const string DetailLevelProperty = "ChatImageDetailLevel";
if (imageContent.Metadata is not null &&
imageContent.Metadata.TryGetValue(DetailLevelProperty, out object? detailLevel) &&
detailLevel is not null)
{
if (detailLevel is string detailLevelString && !string.IsNullOrWhiteSpace(detailLevelString))
{
return detailLevelString.ToUpperInvariant() switch
{
"AUTO" => ChatImageDetailLevel.Auto,
"LOW" => ChatImageDetailLevel.Low,
"HIGH" => ChatImageDetailLevel.High,
_ => throw new ArgumentException($"Unknown image detail level '{detailLevelString}'. Supported values are 'Auto', 'Low' and 'High'.")
};
}
}
return null;
}
private OpenAIChatMessageContent CreateChatMessageContent(OAIChat.ChatCompletion completion, string targetModel, bool retainArgumentTypes, OAIChat.ChatCompletionOptions options)
{
var message = new OpenAIChatMessageContent(completion, targetModel, this.GetChatCompletionMetadata(completion));
if (completion.OutputAudio is ChatOutputAudio outputAudio)
{
var audioContent = new AudioContent(outputAudio.AudioBytes, GetAudioOutputMimeType(options.AudioOptions))
{
Metadata = new Dictionary<string, object?>
{
[nameof(outputAudio.Id)] = outputAudio.Id,View on GitHub (pinned to c028a0c7dc)
Solutions
- Use only 'Auto', 'Low', or 'High' for the ChatImageDetailLevel metadata string.
- Omit the metadata key entirely if you want the default (the method returns null and OpenAI picks a default).
- If storing the enum, use the ChatImageDetailLevel enum instead of a free string.
Example fix
// before image.Metadata["ChatImageDetailLevel"] = "full"; // after image.Metadata["ChatImageDetailLevel"] = "High";
Defensive patterns
Strategy: validation
Validate before calling
static readonly HashSet<string> ValidDetail = new(StringComparer.OrdinalIgnoreCase) { "auto","low","high" };
static void SetImageDetail(ImageContent img, string? d) { if (d is null) return; if (!ValidDetail.Contains(d)) throw new ArgumentException($"Detail must be Auto/Low/High"); img.Metadata["ChatImageDetailLevel"] = d.ToLowerInvariant(); } Type guard
static bool IsValidImageDetail(string? d) => d is null || ValidDetail.Contains(d);
Try / catch
try { await client.GetChatCompletionAsync(history); }
catch (ArgumentException ex) when (ex.Message.Contains("detail level")) { /* remove metadata key and retry */ } Prevention
- Omit the key for default behavior.
- Use only Auto/Low/High tokens.
When it happens
Trigger: Setting imageContent.Metadata["ChatImageDetailLevel"] to a string like 'none', 'full', 'max', or a numeric value, then sending the image.
Common situations: Confusing this with the (separate) enum form; passing a value from another vision API; copy-pasting an unsupported token.
Related errors
- ImageContent must have either Data or a Uri.
- 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/827278a5dd6f82cd.
Report an issue: GitHub.