{"record":{"id":"1fa246034cf18118","repo":"microsoft/semantic-kernel","slug":"auto-invocation-of-tool-calls-may-only-be-used-wit","errorCode":null,"errorMessage":"Auto-invocation of tool calls may only be used with a {nameof(GeminiPromptExecutionSettings.CandidateCount)} of 1.","messagePattern":"Auto-invocation of tool calls may only be used with a (.+?) of 1\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.Google/Core/Gemini/Clients/GeminiChatCompletionClient.cs","lineNumber":969,"sourceCode":"                    InnerContent = reasoningContent.Text\n                };\n                streamingMessage.Items.Add(streamingReasoning);\n            }\n            // Note: Other item types like TextContent are not copied since the main content\n            // is already in streamingMessage.Content\n#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.\n        }\n\n        return streamingMessage;\n    }\n\n    private static void ValidateAutoInvoke(bool autoInvoke, int resultsPerPrompt)\n    {\n        if (autoInvoke && resultsPerPrompt != 1)\n        {\n            // We can remove this restriction in the future if valuable. However, multiple results per prompt is rare,\n            // and limiting this significantly curtails the complexity of the implementation.\n            throw new ArgumentException(\n                $\"Auto-invocation of tool calls may only be used with a {nameof(GeminiPromptExecutionSettings.CandidateCount)} of 1.\");\n        }\n    }\n\n    private static GeminiMetadata GetResponseMetadata(\n        GeminiResponse geminiResponse,\n        GeminiResponseCandidate candidate,\n        string? thoughtSignature = null) => new()\n        {\n            FinishReason = candidate.FinishReason,\n            Index = candidate.Index,\n            PromptTokenCount = geminiResponse.UsageMetadata?.PromptTokenCount ?? 0,\n            CachedContentTokenCount = geminiResponse.UsageMetadata?.CachedContentTokenCount ?? 0,\n            ThoughtsTokenCount = geminiResponse.UsageMetadata?.ThoughtsTokenCount ?? 0,\n            CurrentCandidateTokenCount = candidate.TokenCount,\n            CandidatesTokenCount = geminiResponse.UsageMetadata?.CandidatesTokenCount ?? 0,\n            TotalTokenCount = geminiResponse.UsageMetadata?.TotalTokenCount ?? 0,\n            PromptFeedbackBlockReason = geminiResponse.PromptFeedback?.BlockReason,","sourceCodeStart":951,"sourceCodeEnd":987,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.Google/Core/Gemini/Clients/GeminiChatCompletionClient.cs#L951-L987","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set CandidateCount to 1 (or leave it null/default) when using tool-call auto-invocation.","If multiple candidates are needed, disable auto-invocation by setting ToolCallBehavior to null or MaximumAutoInvokeAttempts to 0, and handle tool calls manually.","Validate settings before the call: if (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0 && settings.CandidateCount is int c && c != 1) settings.CandidateCount = 1;"],"exampleFix":"// before — conflicting settings\nvar settings = new GeminiPromptExecutionSettings\n{\n    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions(),\n    CandidateCount = 3\n};\n\n// after — single candidate for auto-invoke\nvar settings = new GeminiPromptExecutionSettings\n{\n    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions(),\n    CandidateCount = 1\n};","handlingStrategy":"validation","validationCode":"if (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0\n    && settings.CandidateCount is int count && count != 1)\n{\n    throw new ArgumentException(\n        \"CandidateCount must be 1 when tool-call auto-invocation is enabled.\");\n}\n// or auto-fix:\nif (settings.ToolCallBehavior?.MaximumAutoInvokeAttempts > 0)\n    settings.CandidateCount = 1;","typeGuard":"static bool IsAutoInvokeCompatible(GeminiPromptExecutionSettings s) =>\n    s.ToolCallBehavior?.MaximumAutoInvokeAttempts is not > 0\n    || s.CandidateCount is null or 1;","tryCatchPattern":"try { await client.GetChatMessageContentsAsync(history, settings, kernel, ct); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"CandidateCount\"))\n{\n    settings.CandidateCount = 1;\n    await client.GetChatMessageContentsAsync(history, settings, kernel, ct);\n}","preventionTips":["Default CandidateCount to 1 or null when using auto-invocation.","If you need multiple candidates, set MaximumAutoInvokeAttempts to 0 and handle tool calls manually.","Validate settings compatibility before calling the Gemini connector."],"tags":["google","gemini","tool-calling","configuration","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}