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

  1. Use only FunctionChoiceBehavior (preferred) or only ToolCallBehavior, never both.
  2. When migrating, set ToolCallBehavior = null after assigning FunctionChoiceBehavior.
  3. 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

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


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