Model stream ended without a finish reason.
The message
Model stream ended without a finish reason.What it means
The model's reply finished streaming but failed Gemini CLI's check on what a finished reply looks like: no end marker, no text, or a broken tool call. The CLI had already tried four times.
What to do
Send the message again. If the text mentions thoughts, MAX_TOKENS or context, run /compress first. If it keeps happening on an old version, update.
Gemini CLI prints this when a reply from the model streamed in and then failed the CLI's own check on whether it was a finished answer:
Model stream ended without a finish reason.
It's one of nine messages from the same check in version 0.61.0, all starting "Model stream ended". If you've been using the CLI for a while you probably know the older one better:
✕ [API Error: Model stream ended with an invalid chunk or missing finish reason.]
Between them they account for 94 GitHub issues quoting "Model stream ended" and 114 quoting "Invalid stream", which is the error's type name (counts from September 25, 2026). We read the check and the retry loop in the 0.61.0 source, then went back through the issues to see how the wording changed.
What the check looks at
Gemini replies arrive as a stream of chunks. The last one normally carries a finish reason. Once the stream closes, the CLI joins the text, strips invisible characters and HTML comments, and asks a few questions. If the reply contains a tool call, it passes. If not, it fails when:
- no finish reason ever arrived (the message on this page)
- the finish reason says the model produced a malformed or unexpected tool call
- the text is empty and the finish reason names a cause, such as the token limit or a safety block
- the text is empty with no cause given, whether or not the model's reasoning came through
Two of those are skipped when the request you sent was a tool's output going back to the model: a missing finish reason and a plain empty reply. That exception matters later.
What the retries do
Every one of these errors counts as retryable. By default the CLI makes up to four attempts in total, waiting one second, then two, then four between them, and the spinner shows Trying to reach followed by the model name and an attempt counter out of 4. So by the time you read the message, the same request has already failed four times in a row. That surprised us, because the message reads like a single dropped connection.
The retry isn't always a plain resend. Since late August, if the failure was an empty reply or a reply with only reasoning, the CLI adds a line to the end of your turn before trying again, starting [System: You previously returned an empty response or [System: You previously generated thoughts but failed to provide a final user-facing response, asking the model to answer or call a tool.
Where the old wording went
"Invalid chunk or missing finish reason" was what this check printed until a September 22, 2025 change that stopped inspecting each chunk and added the empty-text test, which split it into the specific lines above. Reports of the old one run from June 2025 to the end of that September. One person logged it 14 times in a session, "every few messages or so".
Since a July 31, 2026 change, the interactive CLI swaps some of these for plainer text. An empty reply now shows The model returned an empty response with no text or thoughts. This may be a transient API issue; please try again. and a thoughts-only one suggests /compress, the command that summarizes the conversation to free up context. Run headless and it's written to stderr after [ERROR].
Why it happens
The check is the CLI's, but the empty or unfinished reply comes from the model. That's how a contributor on the repo closed an April report of Model stream ended with empty response text.: "This seems upstream to the model, not harness specific." The thoughts and MAX_TOKENS variants point at a full context window, which is why those two get the /compress advice.
The tool-output exception has a cost. A July report showed Google's backend returning a normal STOP with no text straight after a tool call, and because that case is exempt from the check, the CLI dropped back to the prompt with no error at all. The reporter called it "the number one complaint on my company's gemini slack channel".
What to do
Send the message again. If the text mentions thoughts, MAX_TOKENS or truncation, run /compress first. If you're still seeing the "invalid chunk" line, your CLI is from before September 2025, so update with npm install -g @google/gemini-cli.
Codex has its own mid-stream failure with different causes, covered on “stream disconnected before completion”.
Other lines the same feature prints
Match yours against these if the one at the top of the page is not quite it. They come from the same code and mean related things.
Model stream ended with an invalid chunk or missing finish reason.[API Error: Model stream ended with an invalid chunk or missing finish reason.]Model stream ended with empty response text.Model stream ended with malformed function call.Model stream ended with empty response text but contained reasoning thoughts.Model stream ended due to token limit exhaustion (MAX_TOKENS) with empty response text.The model returned an empty response with no text or thoughts. This may be a transient API issue; please try again.The model returned reasoning thoughts but no final response text. If your context window is near capacity, try using /compress.Invalid stream received from modelInvalid stream: The model returned an empty response or malformed tool call.