microsoft/semantic-kernel · error · NotSupportedException
Unsupported function choice '{config.Choice}'.
Error message
Unsupported function choice '{config.Choice}'. What it means
Thrown in the tool-choice branch of ConfigureFunctionCalling. After mapping FunctionChoice.Auto/Required/None to the corresponding ChatToolChoice, the else branch catches any FunctionChoice enum value not handled (e.g. a future member or an invalid integer cast to FunctionChoice). The unsupported value is reported.
Source
Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs:1349
bool autoInvoke = config?.AutoInvoke ?? false;
if (config?.Functions is { Count: > 0 } functions)
{
if (config.Choice == FunctionChoice.Auto)
{
toolChoice = ChatToolChoice.CreateAutoChoice();
}
else if (config.Choice == FunctionChoice.Required)
{
toolChoice = ChatToolChoice.CreateRequiredChoice();
}
else if (config.Choice == FunctionChoice.None)
{
toolChoice = ChatToolChoice.CreateNoneChoice();
}
else
{
throw new NotSupportedException($"Unsupported function choice '{config.Choice}'.");
}
tools = [];
foreach (var function in functions)
{
tools.Add(function.Metadata.ToOpenAIFunction().ToFunctionDefinition(config?.Options?.AllowStrictSchemaAdherence ?? false));
}
}
return new(tools, toolChoice, autoInvoke, config?.Options);
}
/// <summary>
/// Processes non-function tool calls.
/// </summary>
/// <param name="toolCalls">All tool calls requested by AI model.</param>
/// <param name="chatHistory">The chat history.</param>View on GitHub (pinned to c028a0c7dc)
Solutions
- Use FunctionChoice.Auto, Required, or None only.
- If a new FunctionChoice member is needed, upgrade Connectors.OpenAI to a version that maps it.
- Do not cast arbitrary integers to FunctionChoice.
Example fix
// before
var cfg = new FunctionChoiceBehaviorConfig { Choice = (FunctionChoice)42 };
// after
var cfg = new FunctionChoiceBehaviorConfig { Choice = FunctionChoice.Auto }; Defensive patterns
Strategy: validation
Validate before calling
static readonly HashSet<FunctionChoice> ValidChoices = new() { FunctionChoice.Auto, FunctionChoice.Required, FunctionChoice.None };
static void EnsureChoice(FunctionChoice c) { if (!ValidChoices.Contains(c)) throw new ArgumentException($"FunctionChoice {c} not mapped"); } Type guard
static bool IsValidFunctionChoice(FunctionChoice c) => ValidChoices.Contains(c);
Try / catch
try { await client.GetChatCompletionAsync(...); }
catch (NotSupportedException ex) when (ex.Message.Contains("function choice")) { /* fall back to FunctionChoice.Auto and retry */ } Prevention
- Use only Auto/Required/None.
- Never cast arbitrary integers to FunctionChoice.
When it happens
Trigger: config.Choice is a FunctionChoice value other than Auto, Required, or None — for example a newly added enum member not yet mapped by this connector build, or an integer cast like (FunctionChoice)99.
Common situations: Version skew between the FunctionChoice enum source and the connector; reflection/deserialization forcing an out-of-range enum value.
Related errors
- Data is not available for {cityName}.
- No function result provided in the tool message.
- Unsupported audio output format '{audioOptions.OutputAudioFo
- {nameof(executionSettings.ToolCallBehavior)} and {nameof(exe
- Function call required but no function steps found for agent
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/3c74b2fc9a58e5c2.
Report an issue: GitHub.