microsoft/semantic-kernel · error · NotSupportedException

The provided reasoning effort '{effortLevelObject.GetType()}

Error message

The provided reasoning effort '{effortLevelObject.GetType()}' is not supported.

What it means

Sibling throw to 381: it fires when ReasoningEffort is supplied as an object that is neither the native ChatReasoningEffortLevel enum nor a string. The connector supports exactly those two shapes; anything else (int, bool, JsonElement of non-string kind, anonymous object) has no defined conversion, so the actual runtime type is reported.

Source

Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs:581

        if (effortLevelObject is ChatReasoningEffortLevel effort)
        {
            return effort;
        }

        if (effortLevelObject is string textEffortLevel)
        {
            return textEffortLevel.ToUpperInvariant() switch
            {
                "LOW" => ChatReasoningEffortLevel.Low,
                "MEDIUM" => ChatReasoningEffortLevel.Medium,
                "HIGH" => ChatReasoningEffortLevel.High,
                "MINIMAL" => new("minimal"),
                _ => throw new NotSupportedException($"The provided reasoning effort '{textEffortLevel}' is not supported.")
            };
        }

        throw new NotSupportedException($"The provided reasoning effort '{effortLevelObject.GetType()}' is not supported.");
    }

    protected static ChatWebSearchOptions? GetWebSearchOptions(OpenAIPromptExecutionSettings executionSettings)
    {
        if (executionSettings.WebSearchOptions is null)
        {
            return null;
        }

        if (executionSettings.WebSearchOptions is ChatWebSearchOptions webSearchOptions)
        {
            return webSearchOptions;
        }

        if (executionSettings.WebSearchOptions is string webSearchOptionsString)
        {
            return ModelReaderWriter.Read<ChatWebSearchOptions>(BinaryData.FromString(webSearchOptionsString));
        }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Provide ReasoningEffort as a string ('low'/'medium'/'high'/'minimal') or as a ChatReasoningEffortLevel enum instance.
  2. If the value comes from JSON, ensure it is a JSON string token, not a number or object.
  3. Coerce/normalize the value to a string before assigning it to the settings.

Example fix

// before
settings.ReasoningEffort = 1; // or JsonElement number
// after
settings.ReasoningEffort = "medium";
Defensive patterns

Strategy: type-guard

Validate before calling

object SetReasoningEffort(object value) => value switch { string s when ValidEfforts.Contains(s) => s.ToLowerInvariant(), ChatReasoningEffortLevel => value, _ => throw new ArgumentException("ReasoningEffort must be string or ChatReasoningEffortLevel") };

Type guard

static bool IsSupportedEffortObject(object? o) => o is string s ? ValidEfforts.Contains(s) : o is ChatReasoningEffortLevel;

Try / catch

try { await client.GetChatCompletionAsync(...); }
catch (NotSupportedException ex) when (ex.Message.Contains("reasoning effort")) { settings.ReasoningEffort = "medium"; }

Prevention

When it happens

Trigger: ReasoningEffort is deserialized from JSON into a non-string JsonElement or passed as a numeric/boolean/object value. For example, binding 'reasoning_effort': 1 from config, or feeding a JObject.

Common situations: Loading execution settings from appsettings.json where the value is a number; serializing settings across processes and losing the original type; MCP/config-driven pipelines that emit arbitrary JSON values.

Related errors


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