microsoft/semantic-kernel · error · ArgumentException
{nameof(executionSettings.ToolCallBehavior)} and {nameof(exe
Error message
{nameof(executionSettings.ToolCallBehavior)} and {nameof(executionSettings.FunctionChoiceBehavior)} cannot be used together. What it means
Thrown by GetFunctionCallingConfiguration when BOTH executionSettings.FunctionChoiceBehavior and executionSettings.ToolCallBehavior are non-null. These are two mutually exclusive ways to configure tool/function calling (FunctionChoiceBehavior is the newer model; ToolCallBehavior is the legacy one). Specifying both is ambiguous, so the connector refuses rather than guess which wins.
Source
Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs:1258
}
s_promptTokensCounter.Add(usage.InputTokenCount);
s_completionTokensCounter.Add(usage.OutputTokenCount);
s_totalTokensCounter.Add(usage.TotalTokenCount);
}
private ToolCallingConfig GetFunctionCallingConfiguration(Kernel? kernel, OpenAIPromptExecutionSettings executionSettings, ChatHistory chatHistory, int requestIndex)
{
// If neither behavior is specified, we just return default configuration with no tool and no choice
if (executionSettings.FunctionChoiceBehavior is null && executionSettings.ToolCallBehavior is null)
{
return new ToolCallingConfig(Tools: null, Choice: null, AutoInvoke: false, AllowAnyRequestedKernelFunction: false, Options: null);
}
// If both behaviors are specified, we can't handle that.
if (executionSettings.FunctionChoiceBehavior is not null && executionSettings.ToolCallBehavior is not null)
{
throw new ArgumentException($"{nameof(executionSettings.ToolCallBehavior)} and {nameof(executionSettings.FunctionChoiceBehavior)} cannot be used together.");
}
IList<ChatTool>? tools = null;
ChatToolChoice? choice = null;
bool autoInvoke = false;
bool allowAnyRequestedKernelFunction = false;
FunctionChoiceBehaviorOptions? options = null;
// Handling new tool behavior represented by `PromptExecutionSettings.FunctionChoiceBehavior` property.
if (executionSettings.FunctionChoiceBehavior is { } functionChoiceBehavior)
{
(tools, choice, autoInvoke, options) = this.ConfigureFunctionCalling(kernel, requestIndex, functionChoiceBehavior, chatHistory);
}
// Handling old-style tool call behavior represented by `OpenAIPromptExecutionSettings.ToolCallBehavior` property.
else if (executionSettings.ToolCallBehavior is { } toolCallBehavior)
{
(tools, choice, autoInvoke, int maximumAutoInvokeAttempts, allowAnyRequestedKernelFunction) = this.ConfigureFunctionCalling(kernel, requestIndex, toolCallBehavior);
View on GitHub (pinned to c028a0c7dc)
Solutions
- Use only FunctionChoiceBehavior (preferred) or only ToolCallBehavior, never both.
- When migrating, set ToolCallBehavior = null after assigning FunctionChoiceBehavior.
- If settings are merged/serialized, ensure only one survives the merge.
Example fix
// before settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions; settings.FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(); // after settings.ToolCallBehavior = null; settings.FunctionChoiceBehavior = FunctionChoiceBehavior.Auto();
Defensive patterns
Strategy: validation
Validate before calling
static void EnsureSingleToolBehavior(OpenAIPromptExecutionSettings s) { if (s.FunctionChoiceBehavior is not null && s.ToolCallBehavior is not null) throw new ArgumentException("Set only one of FunctionChoiceBehavior or ToolCallBehavior"); } Type guard
static bool HasSingleToolBehavior(OpenAIPromptExecutionSettings s) => (s.FunctionChoiceBehavior is null) || (s.ToolCallBehavior is null);
Try / catch
try { await client.GetChatCompletionAsync(...); }
catch (ArgumentException ex) when (ex.Message.Contains("cannot be used together")) { settings.ToolCallBehavior = null; /* retry with FunctionChoiceBehavior */ } Prevention
- Prefer FunctionChoiceBehavior; null out ToolCallBehavior when migrating.
- Audit settings merge logic so only one survives.
When it happens
Trigger: Code (or merged settings) that sets both ToolCallBehavior (e.g. KernelFunctionFactory/ToolCallBehavior.AutoInvokeKernelFunctions) and FunctionChoiceBehavior (e.g. FunctionChoiceBehavior.Auto()) on the same OpenAIPromptExecutionSettings.
Common situations: Migrating from ToolCallBehavior to FunctionChoiceBehavior but forgetting to clear the old one; cloning settings that carry a legacy default; mixing snippets from docs of different vintages.
Related errors
- Data is not available for {cityName}.
- No function result provided in the tool message.
- Unsupported function choice '{config.Choice}'.
- Function call required but no function steps found for agent
- The settings must be an OpenAIChatPromptExecutionSettings.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/fac72ca349127b6c.
Report an issue: GitHub.