发布日期:2026-09-03 | 适用版本:Codex 桌面端 26.8xx 系列、Codex CLI 0.15x 系列

"stream disconnected before completion"是 OpenAI Codex 客户端在流式响应尚未收到结束事件时被切断所抛出的错误,自 2026 年 8 月 30 日桌面端 26.825.51511 版本发布后,这条报错在 GitHub openai/codex 仓库的连接类 Issue 中集中出现。根据 2026 年 4 月至 9 月间的十余条 Issue 和 OpenAI 官方配置文档,触发它的原因可以归为五类:新版本对流式结束事件的处理回归、本地代理配置残留或分流规则不一致、单个对话线程体积过大、桌面端恢复会话时的状态卡死,以及网络链路本身的不稳定。界面上"Reconnecting… 2/5"里的分母 5 正是配置项 stream_max_retries 的默认值。本文按"先查本地、再查线程、最后查版本"的顺序给出一套可直接执行的排查命令,并说明使用自定义模型服务的用户需要额外确认的一件事。


这几天为什么突然多了这么多人在报同一个错

8 月 30 日 Codex 桌面端推送了 26.825.51511 版本。从 9 月 1 日起,openai/codex 仓库里以"stream disconnected before completion"为标题的新 Issue 一天能出现好几条,Windows、macOS 都有,报错后缀却各不相同:有人是"stream closed before response.completed",有人是"error sending request for url",还有人看到"tls handshake eof"。

这些后缀其实就是线索。同一个前缀、不同的后缀,对应的是完全不同的病因。把它们混在一起搜,很容易照着别人的方子吃错药。

先搞清楚这个报错在说什么

Codex 和模型服务之间走的是流式响应:服务端一边生成一边推送事件,最后推一个名为 response.completed 的事件表示"说完了"。客户端如果在收到这个结束事件之前就发现连接断了,就会抛出"stream disconnected before completion",然后按配置自动重连。

官方配置文档给出了三个和它直接相关的参数及默认值:stream_max_retries 默认 5 次,也就是你在界面看到的"Reconnecting… x/5";stream_idle_timeout_ms 默认 300000 毫秒,即流上 5 分钟没有任何数据才算超时;request_max_retries 默认 4 次,管的是请求本身的 HTTP 重试。所以"重连 5 次后失败"不是网络有多差的证据,只是重试预算用完了。

五类原因,按后缀对号入座

后缀是"stream closed before response.completed",且升级后才出现。 这是 8 月 30 日新版本的回归。Issue #41989(2026-09-01)的报告者用的是 Windows 11 加自定义模型服务,服务端正常发完 SSE 流并关闭连接,Codex 却没有识别到结束事件,每一轮回答结尾都触发重连。Issue #42254(2026-09-02)则是 macOS 上所有定时自动化任务在 1 到 2 秒内失败,报告者对比发现新版本把自动化上下文从普通文本消息改成了 function_call_output 类型并放在对话首位,部分服务端直接拒绝了这种请求结构。这两条都还是 open 状态,暂无官方修复。

后缀是"error sending request for url",而浏览器和 curl 都能访问同一地址。 优先怀疑本地代理残留。Issue #37863 里一位 macOS 用户在 8 月底用 RUST_LOG=trace 抓到关键一行:Codex 试图通过 127.0.0.1:7890 转发请求,但那个端口上早就没有进程在监听。追查下去,是 git 全局配置里残留的 http.proxy 设置。清掉之后登录和对话立刻恢复。

后缀是"tls handshake eof"或"peer closed connection without sending TLS close_notify",多见于 Windows。 这是代理分流规则的问题。Issue #18647(2026-04-20)的 Windows 用户在本地代理软件规则模式下频繁断流,全局模式却正常。OpenAI 工程师的回复很直接:"这大概率是你代理的问题,不是 Codex 的。"后来有社区用户补了一个数据点:他的 OpenAI 专用代理组被固定在一个失效节点上,而默认组用的是另一个可用节点,规则模式把 Codex 流量强行送进了坏节点。让两个组指向同一个节点后,重连循环消失。

新线程正常,只有某个老线程反复断。 看线程体积。Issue #38212 的 macOS 报告者做了统计:出问题的线程本地文件约 115 MB,含 70 张图片输入、377 条工具输出,经历过 7 次自动上下文压缩,连续三轮回答都在几分钟到四十多分钟后断流,而同一时刻新开的线程完全正常。

界面一直显示"reconnecting / compressing context"转圈,但其实早就没在生成了。 这是桌面端的状态恢复 bug。Issue #19690(2026-04-26)在日志里找到了原因:重启后恢复线程时,上一轮的状态已经是 failed 或 completed,但 markedStreaming 标志仍为 true,界面就一直假装在流式接收。用命令行 codex resume 打开同一个线程可以正常继续。

你现在就能做的排查顺序

按下面的顺序走,大多数情况在第三步之前就能定位。

第一步,查代理残留。三处都要看:

env | grep -i proxy
git config --global --get-regexp '.*proxy.*'
# macOS 额外检查 launchctl 层面的变量
for v in HTTP_PROXY HTTPS_PROXY ALL_PROXY; do launchctl getenv "$v"; done

如果查出指向本地端口的代理但对应软件没在跑,直接清掉:

git config --global --unset http.proxy
git config --global --unset https.proxy

第二步,让 Codex 自己告诉你它在连哪里。桌面端内置的 CLI 可以带详细日志启动,macOS 路径如下:

RUST_LOG=trace RUST_BACKTRACE=full \
  /Applications/Codex.app/Contents/Resources/codex login --device-auth

日志里出现 "proxy(...) intercepts" 字样,就说明流量被本地代理接管了。

第三步,如果你在代理软件的规则模式下断流而全局模式正常,不要只加域名规则,先检查 OpenAI 相关代理组和默认组是否指向同一个可用节点。

第四步,跳过 WebSocket。Issue #27381 有用户反馈,在某些网络下 Codex 会先尝试 WebSocket、超时多次后才回落到 HTTPS,中间白等几分钟。在用户级配置文件 ~/.codex/config.toml 里可以显式关掉:

model_provider = "chatgpt-http"

[model_providers.chatgpt-http]
name = "ChatGPT HTTP"
base_url = "https://chatgpt.com/backend-api/codex"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = false
stream_idle_timeout_ms = 60000
stream_max_retries = 5

注意这个做法有副作用:会话记录和 model_provider 绑定,切换后历史线程在列表里可能看不到,需要用线程 ID 显式恢复。另外官方文档明确指出,项目级 .codex/config.toml 里写 model_providers 会被忽略,必须放在用户级配置。

第五步,老线程断流就开新线程,把关键上下文用一段话交代过去,别继续往一个上百兆的线程里塞图片。

第六步,桌面端假转圈,用命令行接管:

/Applications/Codex.app/Contents/Resources/codex resume <线程ID> --no-alt-screen -C <项目目录>

第七步,以上都排除、且报错是"stream closed before response.completed"并从 8 月 30 日后开始,那就是版本回归,可以先回退到 26.825.41651 或更早版本,并在 Issue #41989 下补充你的环境信息。

用自定义模型服务的人要多查一件事

很多国内用户不是拿 ChatGPT 账号登录,而是在 config.toml 里配了自己的模型服务地址。这类场景下报错更容易被误判成"网络问题",其实要先确认两点。

一是协议。官方配置文档现在只接受 wire_api = "responses",旧的 chat 模式已经不在文档里了。服务端必须按 Responses 协议在流的末尾发出 response.completed 事件,少了这一个事件,Codex 就会把正常结束当成异常断流。Issue #41989 的服务端"正常关闭连接但没发结束事件",恰好卡在这一点上。

二是服务端对请求结构的容忍度。Issue #42254 里自动化任务把 function_call_output 放在对话首位,服务端返回 200 后立刻关流、不给任何错误信息,客户端只能报"stream disconnected"。所以自建或选用兼容服务时,可以先用一个最简单的 Responses 请求验证流式结束事件是否完整,再接进 Codex。像七牛云 Token Plan 这类提供 OpenAI 兼容接口、汇聚多款主流大模型的服务,接入前也建议先跑一遍这个验证,确认流式事件完整再切换日常使用。

写在最后

"stream disconnected before completion"不是一个错,是至少五个错共用了一句话。后缀是分类依据,本地代理是最常见的假性网络故障来源,8 月 30 日之后新出现的 response.completed 类报错则是版本回归,等修复或回退都行。据 OpenAI 官方配置文档,流式重试和空闲超时都可以在用户级 config.toml 中调整;据 Codex CLI 0.153.0(2026-09-03)更新日志,终端会话在与后台服务断连后已经支持自动重连并保留草稿,桌面端对应的修复可以关注后续版本。

本文内容基于 2026 年 9 月 3 日 GitHub openai/codex 仓库公开 Issue 和 OpenAI 官方文档整理,相关 Issue 多数仍处于 open 状态,建议以官方后续更新为准。

延伸阅读