microsoft/autogen · error · InvalidOperationException

The response should contain content but the content is empty

Error message

The response should contain content but the content is empty. FinishReason: {finishReason}, FinishMessage: {finishMessage}

What it means

GeminiMessageConnector.ValidateGenerateContentResponse throws this when the single candidate exists but its Content property is null, meaning the model finished without producing any content. The FinishReason and FinishMessage of the candidate are embedded in the message so the caller can see why generation stopped.

Source

Thrown at dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs:265

            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)
            {
                continue;
            }

            // if result is already a json object, use it as is
            var json = toolCallResult.Result;
            try
            {
                JsonNode.Parse(json);

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Read FinishReason/FinishMessage from the exception text: SAFETY -> relax SafetySettings or rewrite the prompt; MAX_TOKENS -> raise maxOutputTokens; RECITATION -> rephrase.
  2. Set explicit SafetySettings with lower block thresholds on the GenerateContentConfig if content was safety-blocked.
  3. Retry once — transient empty candidates occur occasionally — then propagate the error.
  4. Upgrade the AutoGen.Gemini / Google.Cloud.AIPlatform packages if the empty-content behavior comes from an SDK regression.

Example fix

// before
var config = new GenerateContentConfig { MaxOutputTokens = 5 };

// after
var config = new GenerateContentConfig
{
    MaxOutputTokens = 1024,
    SafetySettings = { HarmCategory.HarmCategoryDangerousContent, HarmBlockThreshold.BlockOnlyHigh },
};
Defensive patterns

Strategy: try-catch

Validate before calling

var c = response.Candidates.FirstOrDefault();
if (c?.Content is null)
{
    Console.WriteLine($"Empty content, finish: {c?.FinishReason} {c?.FinishMessage}");
    // adjust prompt/config before mapping
}

Try / catch

try { var reply = await geminiAgent.SendAsync(msg); } catch (InvalidOperationException ex) when (ex.Message.Contains("content is empty")) { /* raise MaxOutputTokens or rephrase prompt, retry once */ }

Prevention

When it happens

Trigger: Gemini finishes with STOP/SAFETY/MAX_TOKENS/RECITATION but attaches no Content object — e.g. output blocked by safety filters, token limit reached before any token was emitted, or an empty candidate echo.

Common situations: Prompts that trip safety filters; very low maxOutputTokens; model bugs or preview-model quirks returning contentless candidates; API contract changes between Google.Cloud.AIPlatform.Versions.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/3da840ad1902fe14. Report an issue: GitHub.