Gemini CLI 报 Model stream ended 系列错误怎么办?三条流中断的判断方法

2026-08-08

用 Gemini CLI 干活,时不时会撞上这几条:

✕ [API Error: Model stream ended with an invalid chunk or missing finish reason.]
✕ [API Error: Model stream ended with empty response text.]
[API Error: Premature close]

三条说的是同一类事:流式响应没有正常收尾。要么中途来了个不合法的数据块、要么缺了结束标记、要么干脆是空的、要么连接提前关了。

这篇必须先把话说在前面:这三条到核对日为止,都没有公认的解法。 本文不会给你一条「照做就好」的命令——那样写是不负责任的。能给的是:怎么判断这次是不是你的问题、怎么少受损失、以及在什么情况下值得往哪个方向查。

一、先说清楚证据状态

这三条各自对应 GitHub 上的 issue:

报错issue状态issue 里有解法吗
Model stream ended with an invalid chunk or missing finish reason.#7851已关闭,69 条评论没有公认解法
Model stream ended with empty response text.#10672已关闭,50 条评论没有公认解法
Premature close#4230已关闭,18 条评论没有公认解法

三条都是「已关闭」状态。但已关闭不等于已解决——开源仓库里的 issue 可能因为陈旧、重复、或者相关代码变动而关闭。这三条的评论区主要是同样遭遇的汇报,而不是解法讨论。

Gemini CLI 仓库自带的 troubleshooting 文档里也没有收录这三条。 那份文档覆盖的是登录、安装、沙箱、CI 环境等类别,流式响应这块是空白。

所以本文的定位是:告诉你这是什么、怎么判断、怎么减损,而不是假装有答案。

二、这三条在说什么

流式响应的工作方式是:服务端一块一块地把内容发过来,客户端边收边显示,最后收到一个结束标记,表示这次响应完了。

三条报错分别对应这个过程的不同断点:

  • invalid chunk or missing finish reason:收到了不合法的数据块,或者流结束了但没有结束标记。客户端不知道这次到底算完了没有。
  • empty response text:流正常结束了,但内容是空的。协议层面没错,语义层面等于什么都没说。
  • Premature close:连接提前关了。这个最直接——传到一半断了。

这三条里,第二条最特别。它不是「传输出错」,是「传完了但没内容」——所以往网络方向查通常查不出什么。

三、能立刻做的判断

撞上之后,两分钟内可以做这几件事,把范围缩小:

第一,立刻重试一次。

流类问题很多是一次性的。重试就好,说明是偶发;每次都在同一个地方失败,那就有规律可循——看看是不是每次都在处理某个特定文件、或者输出到某个特定长度的时候断

第二,看是不是集中在某一段时间。

如果是某半小时里密集出现、过后又正常,多半是服务端侧的短时状况。这种情况等就完了,改配置是白费力气。

第三,换个模型试。

不同模型的服务容量和行为不完全一样。换一个立刻通,说明跟你的环境无关。

第四,看有没有伴随 429 或 503。

Gemini CLI 里另外两条相关的报错是:

  • API Error: got status: 429 Too Many Requests.(issue #1502,已关闭,127 条评论)
  • 503 - The model is overloaded. Please try again later.(issue #7227,已关闭,70 条评论)

如果流中断和这两条交替出现,那更可能是服务端压力,而不是流协议本身的问题。 429 是你撞了额度或频率上限,503 是服务端过载——这两条都有明确的性质,比流中断好判断得多。

顺带说,429 值得先排除掉,因为它有明确的成因。按官方额度页,免费档的上限是:Google 登录 1000 次/天、60 次/分钟;未付费的 Gemini API Key 是 250 次/天、10 次/分钟。如果你走的是 API key 那条路,每分钟只有 10 次——跑个多步骤任务很容易撞上。

四、减损:控制它发生时你损失多少

既然没法保证它不发生,就把损失降下来。

任务切小。 这条对所有中断类问题都有效。一次让它跑十步,断在第八步,你得花时间确认前面七步做到什么程度;一次跑两三步,断了重来的成本很低。

断了先看,别急着重发。 中断之前它可能已经改过文件、执行过命令。直接重发同一个请求可能会重复执行。先看当前状态,再决定接着做还是重来。

脚本里用退出码判断。 官方文档给了一张退出码表:

退出码类型含义
41FatalAuthenticationError认证过程出错
42FatalInputError输入无效或缺失(仅非交互模式
44FatalSandboxError沙箱环境出错(Docker / Podman / Seatbelt)
52FatalConfigErrorsettings.json 无效或有错
53FatalTurnLimitedError达到会话最大对话轮数(仅非交互模式

这张表里没有专门的流中断退出码——这本身就是有用的信息:如果你的脚本拿到的是 41、52 这种明确的码,那就不是流的问题,按表处理即可;拿到的是别的,才往流中断方向想。

--debug 看更多。 官方给的调试手段是 --debug 标志,交互模式下还可以按 F12 打开调试控制台。断流的时候开着它,能看到比界面上多得多的信息。

五、什么时候该怀疑自己这边

大部分情况下这几条不是你的问题,但有几种情况值得查一下自己:

每次都在同一个地方断。 这不像服务端的随机波动,更像是某个特定输入触发的。试试跳过那个文件、或者把那一步换个说法。

只在企业网/VPN 下复现。 中间设备可能在干预长连接。可以换个网络对比一次——这一步能直接分开「服务端问题」和「网络路径问题」

只在某个特定终端或环境下复现。 换个终端试试。

伴随大量重试和超时。 那更可能是网络质量问题,而不是流协议问题。

六、还有一条长得像但不是一类的

顺带提一条容易被归到「它出错了」里的报错:

0 occurrences found for old_string

这条对应 issue #5629(已关闭)。它不是 API 错误,而是工具调用层面的——改文件的时候,要替换的那段旧内容没匹配上。成因通常是空白、缩进或换行的差异。

认出它的价值在于:这条完全不用往网络、服务端、流协议方向查。 它是个确定性的匹配问题,重试一百次也是同样的结果。

七、总结

  • 这三条到核对日为止都没有公认解法,官方 troubleshooting 也没收录。本文不编解法。
  • empty response text 最特别——流正常结束但内容为空,往网络方向查通常查不出东西。
  • 先重试一次,判断是偶发还是有规律。
  • 看是否伴随 429 / 503——那两条性质明确,比流中断好判断。走免费 API key 的话,每分钟只有 10 次,很容易撞 429。
  • 减损靠任务切小 + 断了先看再决定,别直接重发。
  • 退出码表里没有流中断专用码——拿到 41/52 这种明确的码,说明不是流的问题。
  • 0 occurrences found for old_string 不是一类问题,那是文本匹配失败,重试无用。

本文引用的 issue 编号来自 google-gemini/gemini-cli 仓库,退出码表与调试方法来自该仓库自带的 troubleshooting 文档,额度数字来自官方额度与定价页,核对日 2026-08-08。issue 状态与产品行为会变化,以官方为准。

相关阅读

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。