Skip to content

gemini-3.5-flash with generate_content_stream + automatic function calling stops after tool execution and returns empty final text #2575

@TiagoBelbute

Description

@TiagoBelbute

Summary

When using gemini-3.5-flash with generate_content_stream and automatic function calling enabled, the model executes a tool successfully but then ends the stream with:

  • finish_reason = STOP
  • final candidate content containing only {"text": ""}
  • no visible text
  • no automatic_function_calling_history

The same workflow works with gemini-2.5-flash, and the same logical flow works if we do not rely on AFC streaming.

Date observed

June 9, 2026

Environment

  • Python SDK: google-genai 2.8.0
  • Model: gemini-3.5-flash
  • Method: client.models.generate_content_stream(...)
  • Automatic function calling enabled
  • Python 3.11
  • Also reproduced previously with google-genai 1.50.0

Scenario

We have a tool-based structured-data agent. The expected flow is:

  1. model calls a discovery tool
  2. tool returns a valid candidate
  3. model either continues tool usage or emits final text

In this case, step 2 succeeds, but the model immediately ends the stream with an empty final text candidate.

Minimal observed behavior

User question:

What is the birth rate for SampleTown in 2023?

Tool call executed successfully:

find_metric_candidates(query="birth rate")

Tool result:

{
  "query": "birth rate",
  "result": [
    {
      "id": 101,
      "name": "Crude birth rate",
      "dataset": "public_metrics_table",
      "metric_type": 1,
      "geo_levels": "City, Region, Country",
      "match_source": "name_contains"
    }
  ],
  "row_count": 1
}

But the stream ends with:

{
  "content": {
    "parts": [
      {
        "text": ""
      }
    ],
    "role": "model"
  },
  "finish_reason": "STOP",
  "index": 0
}

No visible text is produced.

Expected behavior

After a successful tool call, the model should either:

  • continue with additional tool calls, or
  • emit a final visible text response

It should not end with STOP and an empty text-only candidate.

Actual behavior

  • tool executes successfully
  • stream returns HTTP 200
  • final chunk has finish_reason=STOP
  • final candidate has text=""
  • no automatic_function_calling_history
  • no visible output

Sanitized diagnostic logs

HTTP Request: POST .../models/gemini-3.5-flash:streamGenerateContent?alt=sse "HTTP/1.1 200 OK"
[Tool] find_metric_candidates called
[Tool] query: birth rate
[Tool] returned 1 row
[DIAG] chunk=1 text_len=0 has_history=False finish_reason=FinishReason.STOP parts=['empty_text']
[DIAG RAW] candidate={'content': {'parts': [{'text': ''}], 'role': 'model'}, 'finish_reason': 'STOP', 'index': 0}

Comparison

  • gemini-2.5-flash works correctly in the same agent/tool flow
  • gemini-3.5-flash fails in AFC streaming mode
  • similar behavior was observed across multiple Gemini 3 family models in this workflow

Workarounds tried

  • prompt changes
  • thinking configuration changes
  • SDK upgrade from 1.50.0 to 2.8.0

The issue still reproduces in AFC streaming mode.

Question

  • Is this a known limitation or bug in gemini-3.5-flash with generate_content_stream + automatic function calling?
  • If this is expected behavior, what is the recommended pattern for Gemini 3.5 in this scenario?

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions