microsoft/semantic-kernel · error · ArgumentException

Auto-invocation of tool calls may only be used with a {nameo

Error message

Auto-invocation of tool calls may only be used with a {nameof(GeminiPromptExecutionSettings.CandidateCount)} of 1.

What it means

Thrown by GeminiChatCompletionClient.ValidateAutoInvoke when tool-call auto-invocation is enabled (autoInvoke is true) and the CandidateCount is not 1. Auto-invocation requires exactly one candidate because the tool-call dispatch logic assumes a single result. Multiple candidates with tool calls would create ambiguity in which tool call results to feed back.

Source

Thrown at dotnet/src/Connectors/Connectors.Google/Core/Gemini/Clients/GeminiChatCompletionClient.cs:969

                    InnerContent = reasoningContent.Text
                };
                streamingMessage.Items.Add(streamingReasoning);
            }
            // Note: Other item types like TextContent are not copied since the main content
            // is already in streamingMessage.Content
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
        }

        return streamingMessage;
    }

    private static void ValidateAutoInvoke(bool autoInvoke, int resultsPerPrompt)
    {
        if (autoInvoke && resultsPerPrompt != 1)
        {
            // We can remove this restriction in the future if valuable. However, multiple results per prompt is rare,
            // and limiting this significantly curtails the complexity of the implementation.
            throw new ArgumentException(
                $"Auto-invocation of tool calls may only be used with a {nameof(GeminiPromptExecutionSettings.CandidateCount)} of 1.");
        }
    }

    private static GeminiMetadata GetResponseMetadata(
        GeminiResponse geminiResponse,
        GeminiResponseCandidate candidate,
        string? thoughtSignature = null) => new()
        {
            FinishReason = candidate.FinishReason,
            Index = candidate.Index,
            PromptTokenCount = geminiResponse.UsageMetadata?.PromptTokenCount ?? 0,
            CachedContentTokenCount = geminiResponse.UsageMetadata?.CachedContentTokenCount ?? 0,
            ThoughtsTokenCount = geminiResponse.UsageMetadata?.ThoughtsTokenCount ?? 0,
            CurrentCandidateTokenCount = candidate.TokenCount,
            CandidatesTokenCount = geminiResponse.UsageMetadata?.CandidatesTokenCount ?? 0,
            TotalTokenCount = geminiResponse.UsageMetadata?.TotalTokenCount ?? 0,
            PromptFeedbackBlockReason = geminiResponse.PromptFeedback?.BlockReason,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Set CandidateCount to 1 (or leave it null/default) when using tool-call auto-invocation.
  2. If multiple candidates are needed, disable auto-invocation by setting ToolCallBehavior to null or MaximumAutoInvokeAttempts to 0, and handle tool calls manually.
  3. Validate settings before the call: if (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0 && settings.CandidateCount is int c && c != 1) settings.CandidateCount = 1;

Example fix

// before — conflicting settings
var settings = new GeminiPromptExecutionSettings
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions(),
    CandidateCount = 3
};

// after — single candidate for auto-invoke
var settings = new GeminiPromptExecutionSettings
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions(),
    CandidateCount = 1
};
Defensive patterns

Strategy: validation

Validate before calling

if (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0
    && settings.CandidateCount is int count && count != 1)
{
    throw new ArgumentException(
        "CandidateCount must be 1 when tool-call auto-invocation is enabled.");
}
// or auto-fix:
if (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0)
    settings.CandidateCount = 1;

Type guard

static bool IsAutoInvokeCompatible(GeminiPromptExecutionSettings s) =>
    s.ToolCallBehavior?.MaximumAutoInvokeAttempts is not > 0
    || s.CandidateCount is null or 1;

Try / catch

try { await client.GetChatMessageContentsAsync(history, settings, kernel, ct); }
catch (ArgumentException ex) when (ex.Message.Contains("CandidateCount"))
{
    settings.CandidateCount = 1;
    await client.GetChatMessageContentsAsync(history, settings, kernel, ct);
}

Prevention

When it happens

Trigger: Setting GeminiPromptExecutionSettings.ToolCallBehavior with MaximumAutoInvokeAttempts > 0 while also setting CandidateCount to a value other than 1. The autoInvoke flag is computed as: kernel is not null AND ToolCallBehavior?.MaximumAutoInvokeAttempts > 0 AND inflight limit not exceeded. If autoInvoke is true and CandidateCount != 1, this throws.

Common situations: Enabling function calling / plugins and simultaneously requesting multiple response candidates for A/B comparison. Using a shared settings object that defaults CandidateCount > 1. Misunderstanding that auto-invoke only works with single-candidate responses.

Related errors


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