"Fix Gemini TTS Streaming Truncation (finishReason OTHER)"
"If your gemini tts streamGenerateContent call dies mid-audio with finishReason OTHER, you're hitting a real, documented streaming abort. Here's the fix."
You press play. The first forty seconds of narration are flawless — then silence. The response was HTTP 200, no exception, no error field anywhere. But the WAV file is half the length it should be, and buried in the final stream chunk is the culprit: finishReason: OTHER . Worse, you're billed for the AUDIO tokens of the broken output. This is the real gemini tts streamGenerateContent truncated audio bug that production teams have been reporting since June 2026 — and it is not your code's fault. Once you know how to detect it, the fix is mechanical: stream, validate the audio you received, retry, and fall back to chunked non-streaming generation. Fix truncated Gemini TTS audio from streamGenerateContent (finishReason OTHER) Here's what the failure looks like in the wild on gemini-3.1-flash-tts-preview , same request body on both endpoints: Text length ~Audio streamGenerateContent generateContent 50 words ~20s STOP / STOP / STOP STOP 150 words ~57s STOP / STOP / STOP STOP 200 words ~70s OTHER / STOP / STOP STOP 300+ words ~106s+ OTHER / OTHER / OTHER STOP (full audio) Streaming reliably truncates past roughly 60–70 seconds of audio, while non-streaming returns the complete audio every time. The truncated response is HTTP 200 with a few PCM chunks and a final finishReason: OTHER — no exception to catch, which is why naive integrations ship the broken file silently. Why the stream dies past ~60 seconds of audio A systematic audit of all 30 prebuilt voices (run twice, two hours apart, same 141-word text) nailed the shape of this bug: audit 1 completed 15/30 voices, audit 2 completed only 7/30 — and the failing set *flipped* between runs. It is not voice-specific; it looks like random infra-level aborts, with failure rates swinging between ~50% and 75%…