Codex 的 /compact 一直失败怎么办?那个 150 秒不是巧合
在 Codex CLI 里敲 /compact,转了很久,最后来一句:
Error running remote compact task
或者更长的形态:
Error running remote compact task: stream disconnected before completion: error sending request
对应 GitHub 上的 issue #14860(已关闭,104 条评论)和 #15046(仍开放)。
这篇讲的重点不是「怎么修」——这条后来是被官方修掉的——而是从这个案例里能学到的一个排查技巧:报错前等了多久,往往比报错文本本身更能说明问题。
一、先说证据状态与修复状况
Codex 仓库里没有官方 troubleshooting 文档(代码搜索按文件名 + 目录遍历都确认过)。所以本文引用的是 issue 里的公开内容。
关于修复状况,issue #14860 里有两条关键信息:
- issue 中有一段被引用的回复,明确否定了某个「打补丁式」的方案:「那不是个好办法,它掩盖了底层的延迟问题。我们一直在解决根本原因。」
- issue 后期有评论说 「现在好了,感谢 OAI 的工作」,issue 已关闭
所以对今天的你,第一动作很明确:升级版本。 一个已经被修的问题,用旧版本硬扛没有意义。原报告者的环境是 codex-cli 0.114.0——如果你的版本比这个还旧或者接近,升级的优先级最高。
二、那个 150 秒:报错前的等待时间是线索
issue #14860 的原报告里有一段分析很值得学习。他指出:
/compact 会在大约 150 秒后失败,而这个数字是 30 秒超时 × 4 次重试。
并且他明确指出:报错消息掩盖了真实原因。
这个观察方法比这个具体结论更有价值。
为什么等待时长是线索
一条报错在你面前出现之前,程序可能已经默默重试了好几轮。而报错文本通常只描述最后一次失败的表象,不会告诉你「我已经试了四次」。
于是就出现了这种情况:报错说「连接断了」,你以为是网络抖了一下;实际上是连续四次、每次等三十秒都没等到响应——那不是抖动,那是持续性的。这两种情况的处理方向完全不同。
怎么用这个方法
下次遇到报错,先问自己一句:它让我等了多久?
- 立刻报错(一两秒内) → 大概率是本地就能判断的问题:配置错、认证没通过、参数不合法。没有走到网络那一层。
- 等了十几秒 → 可能是单次请求超时
- 等了一两分钟甚至更久 → 几乎一定有重试机制在里面。真实的失败次数是你看到的报错的好几倍
第三种情况下,值得去查这个工具的重试参数:重试几次、每次超时多久、退避策略是什么。知道了这些,你就能反推出「实际发生了什么」,而不只是看到「最后一次失败了」。
三、报错文本误导人的两种典型
issue #14860 那条「报错消息掩盖了真实原因」很典型。报错文本会误导人,通常是这两种方式:
第一种:报了最表层的症状。
底层是超时,表层报「连接断开」;底层是权限不足,表层报「流中断」。你按表层去查,永远查不到。
破解办法:看等待时间、看是否可重现、看换个条件是否还发生。 这些都是报错文本之外的信息。
第二种:报了转发过来的错误。
一个操作内部调了别的东西,里面出错了,外层包一层自己的描述再抛出来。你看到的是外层的描述,真因在里层。
Error running remote compact task: stream disconnected before completion: error sending request 这条正好是个例子——它有三层:
Error running remote compact task(这是外层:远程压缩任务失败了)stream disconnected before completion(中层:流没传完就断了)error sending request(内层:请求发送出错)
从右往左读,越靠右越接近真因。 这是读嵌套报错的通用技巧。
四、如果升级之后还是失败
升级是第一动作,但如果升完还有问题,可以从这几个方向看:
第一,看是不是上下文实在太大。 /compact 的工作是把长对话总结成短摘要,对话越长,这个操作本身越重。如果你是在一个超长会话里第一次压缩,负担会比日常压缩大得多。
第二,试试在对话没那么长的时候压。 这是个通用规律:压缩留有余量时成功率更高。别等到实在装不下了才想起来压。
第三,看是不是网络路径慢。 既然原始分析指向的是延迟问题,那链路质量就有影响。换个网络环境试一次,能快速判断。
第四,把长任务拆开。 如果你的工作方式是「一个会话干到底」,那压缩迟早是要面对的。切成几个会话、每个会话干一件事,能绕开大部分上下文管理的麻烦。
第四条是最治本的。 上下文压缩类的问题,本质上都是「单个会话装的东西太多」的后果。
五、这个案例值得记住的三件事
第一,等待时长是免费的线索。 它不需要你开日志、不需要你懂内部实现,就是看一眼时间。而它能告诉你「有没有重试」——这是个很关键的分岔。
第二,嵌套报错从右往左读。 冒号分隔的多层描述里,最右边那段最接近真因。
第三,issue 已关闭不代表白看。 这条 issue 虽然修了,但里面的分析方法(推算重试结构、指出报错误导性)是可以迁移到别的问题上的。读 issue 的价值有时不在于拿到解法,而在于看别人怎么排查。
六、顺带:Codex 的其他几条
同一批 issue 里还有几条,简单记一下形态,撞上时能快速对号:
| 报错 | issue | 状态与要点 |
|---|---|---|
Oops, an error has occurred(VS Code 里看 Diff) | #35058 / #35481 | 已关闭。社区办法是降级扩展到 26.715.61943 并关自动更新 |
stream disconnected before completion(登录后第一条消息) | #1581 | 已关闭。社区线索指向账号需完成组织验证才能用默认模型,换个模型能快速验证 |
Error starting conversation(VS Code 扩展开新对话) | #2841 | 已关闭。社区提到 Windows 支持为实验性;有「发消息后趁加载切模型」的绕法 |
macOS packaging error: SkyComputerUseClient built for macOS 15.0 crashes on macOS 14.x | #18755 | 仍开放。系统版本不匹配导致的崩溃 |
最后那条值得单独提一句:它是本组里唯一一条成因写在标题里的——为 macOS 15.0 构建的东西在 14.x 上崩了。这类报错不用排查,看一眼就知道是版本不匹配。
七、总结
- 这条已经被官方修掉了(issue #14860 已关闭,有「现在好了」的反馈),第一动作是升级版本。
- 那个 150 秒是 30 秒超时 × 4 次重试——原报告者的这个推算示范了一个通用技巧:报错前等了多久,能告诉你有没有重试机制在里面。
- 立刻报错 = 本地就判断出来了;等一两分钟才报 = 里面有重试,这两种的处理方向完全不同。
- 嵌套报错从右往左读,越靠右越接近真因。
- 升级后仍失败的话:别等上下文满了才压;把长任务拆成多个会话——这是治本的做法。
- Codex 仓库内没有官方 troubleshooting 文档,本文内容均来自公开 issue,官方未在文档中确认。
本文引用的 issue 编号与内容来自 openai/codex 仓库 issue #14860、#15046、#35058、#35481、#1581、#2841、#18755 的公开内容,核对日 2026-08-08。版本与修复状况会变化,以官方为准。