Repository navigation
Description
Summary
When using Gemini 2.5 Flash with ThinkingConfig (include_thoughts=True or omitted), thought/reasoning content sometimes appears in the regular text field of response parts with a "THOUGHT:" prefix, but no part has part.thought=True. All parts have thought: null and has_thought_signature: false.
Per the Gemini thinking docs, thought content should be returned as separate parts with the thought boolean set to true. Instead, it arrives as literal text in normal text parts.
Environment
- Package: google-genai 1.64.0 (also observed with 1.57.0)
- Model: gemini-2.5-flash
- Backend: Vertex AI (me-west1, global)
- Mode: Streaming (
generate_content_stream) - Python: 3.11
Steps to Reproduce
- Configure
ThinkingConfigwiththinking_budget=128(or similar) for gemini-2.5-flash - Call
client.aio.models.generate_content_stream()with a prompt that triggers reasoning - Iterate over streamed chunks and inspect
chunk.candidates[0].content.parts - Observe: thought content appears in
part.textwith"THOUGHT:"prefix, butpart.thoughtisNonefor all parts
Expected Behavior
- Thought content should be in parts with
part.thought=True - Client code can filter by
getattr(part, "thought", False)to separate thoughts from answer text
Actual Behavior
- Thought content appears in
part.textwith"THOUGHT:"prefix - All parts have
part.thought is Noneandpart.thought_signature is None - Part-level filtering (
if part.thought: continue) never triggers - We must use text-level filtering (strip
THOUGHT:blocks) as a workaround
Diagnostic Data (from production log)
{
"event": "gemini_thought_leak_diagnostic",
"model": "gemini-2.5-flash",
"vertex_region": "global",
"raw_response": "THOUGHT: The user chose option 2 for character dynamics...\n\n[actual response text]",
"removed_blocks_count": 1,
"total_chars_removed": 243,
"thought_parts_filtered": 0,
"chunks_metadata": [
{"parts": [{"thought": null, "has_thought_signature": false, "text_length": 2}], "thought_parts_filtered": 0},
{"parts": [{"thought": null, "has_thought_signature": false, "text_length": 77}], "thought_parts_filtered": 0}
]
}Key observation: thought_parts_filtered: 0 — no parts were marked as thought by the API, yet we had to remove a 243-char THOUGHT: block from the text.
Workaround (not effective)
We tried to strips THOUGHT: blocks from the concatenated text stream when they appear at block boundaries but it was not working. Also resending was not helping nor changing params like temperture
Question
Is this a known API/streaming behavior? Should thought content ever appear in part.text without part.thought=True? If so, is there a recommended way to detect and filter it at the SDK level?
Activity
Venkaiahbabuneelam commentedon Mar 12, 2026
Hey @itaihochman-cesura , Thanks for reaching out us!
I tried the code shared by you and did not observe any error. Please find the +gist
Thanks
msnidal commentedon Mar 13, 2026
Have been experiencing similar issues on gemini 3.1 flash lite preview, where the thought parts of the response were not being flagged with the
thoughtbool flag and the response chunk.textproperty was therefore unable to distinguish them from the normal parts of the response. It's still unclear to me whether this is an API, model, or an SDK issue tbh.I am finding setting- After some testing, the only consistent way I found to solve the issue was doing a structured output into a wrapped pydnatic structure with ainclude_thoughts=Falseon the thinking config appears to be effectively solving this though, and I'm still receiving the thought signatures as well which is nice.reasoningandtextfield.If you truly need the thought text summaries I would recommend just wrapping your response in a structured output and including a thought property there instead for the time being.
itaihochman-cesura commentedon Mar 15, 2026
It happens to me quite q lot in unpredictable way - it is hard to reproduce but it keeps happening on several models including gemini 3.1 flash, gemini 2.5 flash and gemini 2.5 pro (didnt check on 3.1 pro yet).
Wrapping is a good idea but it looks that there is a real bug somewhere.
BTW, happens with both include_thoughts=False and include_thoughts=True
Venkaiahbabuneelam commentedon Mar 18, 2026
Any update on my comment.?
ChiragAga401 commentedon Mar 18, 2026
I am also experiencing this This does not happen every time so it is hard to check but sometimes even when told not to include any reasoning or thoughts it will still do so
itaihochman-cesura commentedon Mar 18, 2026
@Venkaiahbabuneelam - I can't open the gist... can you give me access?
github-actions commentedon Mar 26, 2026
This issue has been marked as stale because it has been open for 7 days with no activity. It will be closed in 2 days if no further activity occurs.
arnaud-secondlayer commentedon Mar 30, 2026
Same here, this is not systematic but not difficult to reproduce either.
Using
gemini-2.5-flashwith a thinking configVenkaiahbabuneelam commentedon Mar 31, 2026
Hi @itaihochman-cesura,
I have provided access to the Gist, please check and confirm.
Thansk
6 remaining items
Venkaiahbabuneelam commentedon Apr 15, 2026
Hi @arnaud-secondlayer,
Could you please try the latest version of genai? In my environment, we are currently using (>=1.68.0).
Thanks
github-actions commentedon Apr 23, 2026
This issue has been marked as stale because it has been open for 7 days with no activity. It will be closed in 2 days if no further activity occurs.
arnaud-secondlayer commentedon Apr 23, 2026
I looks OK for me now
Venkaiahbabuneelam commentedon Apr 24, 2026
Thanks for your confirmation @arnaud-secondlayer.
github-actions commentedon May 2, 2026
This issue has been marked as stale because it has been open for 7 days with no activity. It will be closed in 2 days if no further activity occurs.
github-actions commentedon May 4, 2026
This issue was closed because it has been inactive for 9 days. Please post a new issue if you need further assistance. Thanks!
Extend the reasoning-text fix to Gemini: includeThoughts, and split t…