microsoft/autogen · error · InvalidOperationException
The response should contain exactly one candidate.
Error message
The response should contain exactly one candidate.
What it means
GeminiMessageConnector.ValidateGenerateContentResponse requires every GenerateContentResponse to carry exactly one candidate, because PostProcessMessage/PostProcessStreamingMessage index Candidates[0] unconditionally. If response.Candidates.Count is 0 (or >1) this InvalidOperationException is thrown before any part inspection.
Source
Thrown at dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs:256
return ProcessTextMessage(textMessage, agent);
}
return [];
}
else
{
var toolCallContents = ProcessToolCallMessage(toolCallAggregateMessage.Message1, agent);
var toolCallResultContents = ProcessToolCallResultMessage(toolCallAggregateMessage.Message2, agent);
return toolCallContents.Concat(toolCallResultContents);
}
}
private void ValidateGenerateContentResponse(GenerateContentResponse response)
{
if (response.Candidates.Count != 1)
{
throw new InvalidOperationException("The response should contain exactly one candidate.");
}
var candidate = response.Candidates[0];
if (candidate.Content is null)
{
var finishReason = candidate.FinishReason;
var finishMessage = candidate.FinishMessage;
throw new InvalidOperationException($"The response should contain content but the content is empty. FinishReason: {finishReason}, FinishMessage: {finishMessage}");
}
}
private IEnumerable<IMessage> ProcessToolCallResultMessage(ToolCallResultMessage toolCallResultMessage, IAgent _)
{
var functionCallResultParts = new List<Part>();
foreach (var toolCallResult in toolCallResultMessage.ToolCalls)
{
if (toolCallResult.Result is null)View on GitHub (pinned to 027ecf0a37)
Solutions
- Inspect response.PromptFeedback.BlockReason for zero-candidate responses and adjust the prompt or SafetySettings.
- Ensure candidateCount is left at 1 in GenerateContentConfig — the connector cannot merge multiple candidates.
- Catch InvalidOperationException and treat it as a blocked/failed generation, falling back to a rephrased prompt.
- Upgrade AutoGen.Gemini for improved handling of blocked responses.
Example fix
// before
var config = new GenerateContentRequest { Config = new GenerateContentConfig { CandidateCount = 2 } };
// after
var config = new GenerateContentRequest { Config = new GenerateContentConfig { CandidateCount = 1 } }; Defensive patterns
Strategy: validation
Validate before calling
if (response.Candidates is null || response.Candidates.Count != 1)
{
var block = response.PromptFeedback?.BlockReason;
// treat as blocked/failed generation, do not call the connector
} Try / catch
try { var reply = await geminiAgent.SendAsync(msg); } catch (InvalidOperationException ex) when (ex.Message.Contains("exactly one candidate")) { /* blocked prompt: rewrite and retry */ } Prevention
- Never set CandidateCount > 1 with this connector
- Check PromptFeedback on suspicious prompts
- Relax SafetySettings only as needed
When it happens
Trigger: Any GeminiAgent reply where the API returns zero candidates — typically when the prompt/request is blocked (safety, prohibited content, recitation) or the response is an error-ish payload with an empty candidate list; or a candidateCount > 1 configuration.
Common situations: Safety settings block the prompt (promptFeedback.blockReason set, candidates empty); requesting candidateCount > 1 in GenerateContentConfig; API version drift where blocked responses no longer include a placeholder candidate.
Related errors
- Unsupported message type: {m.GetType()}
- The response should contain content but the content is empty
- Unsupported message type: {message.GetType()}
- Invalid ImageMessage, the data or url must be provided
- Message type {m.GetType()} is not supported.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/c885340da3e8e7bb.
Report an issue: GitHub.