回合进行中追问一句、回复问题卡片,或者中途打断,Codex 随即停下并显示:
{"type":"error","status":400,"error":{"type":"invalid_request_error","message":"Responses WebSocket messages must have type response.create."}}目前公开的案例里,这条报错都不是 OpenAI 服务器返回的,而是本机的 codex-router(一个让 Codex 接入 Kimi、DeepSeek 等外部模型的本机路由代理)写出来的。旧版 codex-router 在 WebSocket 连接上只接受 response.create 这一种消息;Codex 在回合中途收到你的新输入时,会在同一条连接上再发一条 response.interrupt,旧版代理把它当成非法请求,回了 400,这个回合就断了。
修复已经在 2026 年 10 月 12 日合并进 codex-router 的 main 分支(PR #1004)。你该做什么,取决于 codex-router 是怎么装的:
| 你的情况 | 下一步 |
|---|---|
| 用 README 推荐的一行安装脚本装的(受管 Git checkout) | ./bin/model-router codex update,再 ./bin/model-router codex doctor --fix,完全退出并重开 Codex |
| 用 Homebrew 装的 | 截至 2026 年 10 月 22 日,brew upgrade 只能拿到不含修复的 v0.6.0;先用临时办法,或改用安装脚本 |
| 暂时不能动 codex-router | 在 [features] 下写 instant_interrupt = false,未经实测,追问要等当前步骤结束 |
| 已经不需要外部模型 | codex-router uninstall(Homebrew)或 ./bin/model-router codex uninstall(checkout) |
config.toml 里没有任何本机代理 | 不属于这个已知原因,按后文的方式到 openai/codex #52221 报告 |
这条 400 是谁报的:本机 codex-router,不是 OpenAI
Codex 和模型服务之间通常走 Responses WebSocket:一条长时间保持的连接,双方在上面一条一条地发 JSON 消息(也叫“帧”)。每开始一个回合,Codex 发一条 type 为 response.create 的消息。
在 codex-router 0.6.0 和修复之前的 main 代码里,src/responses-websocket.mjs 有一道检查:收到的消息只要 type 不是 response.create,就回 HTTP 400、invalid_request_error 和这句原文(codex-router #1019 引用了这段代码)。报错里的英文句子就是这样来的。
为什么只在回合中途追问时出现
截至 2026 年 10 月 22 日,Codex 源码里有一个默认开启的功能 instant_interrupt。开启时,回合进行中你发追问、回复问题卡片(英文界面里叫 follow-up、question card,也就是“中途引导”,steering),Codex 会抢占正在生成的响应:在同一条连接上发出第二条消息,并等待 response.interrupt.accepted 或 response.interrupt.failed 的回复:
{"type":"response.interrupt","response_id":"…","mode":"discard_partial_items"}这段逻辑在 openai/codex 源码的 responses_websocket.rs 里,只在响应已经开始之后才会发出。所以安静地等回合跑完不会触发报错,回合中途一插话就会。#52221 里的报告者在日志中也看到同样的顺序:先是 TurnInput mode: Steer,紧接着就是这个 400。

有人猜 Codex 发的是 response.steer。OpenAI 公开的 steering 指南确实为中途引导定义了 response.steer,但截至 2026 年 10 月 22 日,Codex 源码里中途打断发的是 response.interrupt,后者在公开的 API 指南里没有记载。对一个只放行 response.create 的代理来说,这两种消息都会被拒。
用 gpt-6.1-sol 这类原生模型也会出现
很多人装 codex-router 是为了接外部模型,切回 OpenAI 的原生模型后,不会想到请求还在经过它。原因在 codex-router 写进 ~/.codex/config.toml 的受管配置块:
# BEGIN codex-router-managed
openai_base_url = "http://127.0.0.1:4202/_codex-router/<generated-capability>/v1"
...
# END codex-router-managedopenai_base_url 改的是 Codex 内置 OpenAI provider 的地址,所以原生 GPT 模型的回合同样发到 127.0.0.1:4202,经由 codex-router 转发。#52221 里使用 gpt-6.1-sol 的几位报告者,事后检查配置时都发现了这一行。
这是 codex-router 旧版与 Codex 中途打断机制之间的兼容缺口,codex-router 上游已经修复。
三处确认:config.toml、报错末尾、codex-router 版本
1. config.toml 有没有把请求导向本机代理
macOS / Linux:
grep -nE "openai_base_url|4202|codex-router" ~/.codex/config.tomlWindows PowerShell:
Select-String -Path "$env:USERPROFILE\.codex\config.toml" -Pattern "openai_base_url","4202","codex-router"看到 openai_base_url 指向 127.0.0.1:4202,或者有 # BEGIN codex-router-managed、[model_providers.codex-router],就说明 Codex 的请求经过 codex-router。不熟悉这个文件的位置和结构,可以先看《Codex 沙箱与 config.toml:权限、批准和网络怎么配》。
注意: _codex-router/ 后面那一段是本机调用的凭证。不要把完整地址贴进 issue、群聊或截图,需要说明时写成 127.0.0.1:4202/…/v1。
2. 报错末尾是 response.create 还是 or response.interrupt
修复之后,codex-router 的检查同时放行 response.create 和 response.interrupt,遇到其他类型时的报错文字也变了:
| 报错结尾 | 说明 |
|---|---|
must have type response.create. | 正在运行的 codex-router 早于修复 |
must have type response.create or response.interrupt. | 已是修复后的版本,Codex 发了 codex-router 仍不认识的另一种消息,属于新问题 |
3. codex-router 版本是否包含修复
用安装脚本装的,checkout 默认在 ~/.local/share/codex-router(macOS / Linux)。修复的合并提交是 a0ceb5e6:
git -C ~/.local/share/codex-router merge-base --is-ancestor a0ceb5e6dd9c5c4322cf8405620af607f226ca95 HEAD && echo "已包含修复" || echo "未包含修复"用 Homebrew 装的:
brew list --versions codex-router输出 codex-router 0.6.0 就是不含修复的版本。
代码更新了不等于已经生效:更新前启动的 codex-router 进程会一直跑旧代码,直到它重启。
另外可以运行 codex features list,看 instant_interrupt 一行的状态。如果它已经关闭,报错却照样出现,就超出了上面的解释,按最后一节的方式报告。
一行安装脚本装的:更新到 main 并运行 doctor --fix
cd ~/.local/share/codex-router
./bin/model-router codex update
./bin/model-router codex doctor --fix几个前提和细节(来自 codex-router README):
update要求当前在main分支,且没有改动过被跟踪的文件;未跟踪的文件不影响。加--force会丢弃被跟踪文件的改动。- 更新前的版本会保留为本地回滚点,有问题可以
./bin/model-router codex rollback。 - 已经手动
git pull过,也照样跑一次update。重新运行安装脚本同样会从main更新。 doctor --fix让生成的配置和后台服务跟新代码对齐。之后完全退出 Codex(不只是关窗口)再重新打开;如果 codex-router 是在前台终端里跑的,手动重启它。
改完用上一节第 3 步再确认一次,然后在回合进行中发一句追问试试。#52221 里有位 Windows 用户把这个修复移植到本机后,在桌面版里回复问题卡片,回合正常继续了;这只是一次测试,不代表长期稳定。
修复后的行为是:收到 response.interrupt 时取消本机发往上游的请求,丢弃未完成的内容,以 response.incomplete(原因 interrupted)结束这次响应,同一条连接继续可用。PR 里也写明,它取消的是本机的 HTTP 请求,不保证外部模型服务停止对已经发出的生成计费。用按量付费的外部模型时,频繁中途打断仍可能产生费用。
Homebrew 装的:brew upgrade 截至 10 月 22 日拿不到修复
codex-router 最新的正式版本是 2026 年 9 月 15 日发布的 v0.6.0,早于 10 月 12 日合并的修复;Homebrew 公式下载的正是 v0.6.0 的源码包。所以截至 2026 年 10 月 22 日,brew upgrade codex-router 不会带来这个修复。

可以这样选:
- 愿意等下一个版本:关注 releases 页面,新版本发布后再
brew upgrade codex-router,等待期间用下一节的临时办法。 - 想马上修好:先
codex-router uninstall移除后台服务和受管的 Codex 配置,再brew uninstall codex-router,然后按 README 改用推荐的安装脚本。安装脚本会从main拉代码,并重新引导你选择 provider。
暂时不能更新:instant_interrupt = false 的代价
在 ~/.codex/config.toml 里加入:
[features]
instant_interrupt = false文件里已经有 [features] 表时,把这一行加到原有的表下面,不要再写一个 [features],否则 TOML 会因为重复的表而解析失败。保存后完全退出并重开 Codex。
按 Codex 源码的逻辑,关掉 instant_interrupt 后,中途追问不再抢占正在运行的响应,也就不会发出 response.interrupt。代价是追问要等当前这一步结束才生效,中途纠偏会慢一些。这个办法没有经过实测,#52221 里最早指出原因的评论者也说自己没有试过;instant_interrupt 在源码里仍标为开发中的功能,后续版本可能改名或移除。
把它当成过渡手段:codex-router 更新到含修复的版本后,删掉这一行。
不再需要外部模型:用 uninstall 或 disable 绕开代理
如果你已经不用通过 codex-router 接入的模型,直接把它从 Codex 的请求路径上拿掉:
| 安装方式 | 命令 |
|---|---|
| Homebrew | codex-router uninstall,之后可以 brew uninstall codex-router |
| 安装脚本(checkout) | ./bin/model-router codex uninstall;只想移除 Codex 集成、保留其他部分,用 ./bin/model-router codex disable |
README 建议用这些命令,而不是手动删除 config.toml 里的受管配置块。执行后 openai_base_url 不再指向 127.0.0.1:4202,原生模型直接连 OpenAI。#52221 里有用户移除 codex-router 后,这条报错就不再出现。代价是经 codex-router 接入的 Kimi、DeepSeek 等外部模型在 Codex 里用不了了。checkout 方式的 uninstall 会保留代码、日志、备份和 provider 凭证,之后想恢复不必从头配置。
这条 400 的相关疑问:追问会不会丢、Remote 会不会出现
这是 OpenAI 服务器的故障吗?
已知案例不是。报错文字出自 codex-router 的源码;附带配置信息的报告里,openai_base_url 都指向本机地址,其中多数写明是 codex-router 的 127.0.0.1:4202。截至 2026 年 10 月 22 日,OpenAI 还没有在 #52221 里回复。
brew upgrade codex-router 能修好吗?
截至 2026 年 10 月 22 日不能。Homebrew 公式固定在 v0.6.0,修复只在 main 上,要等下一个正式版本。
被打断时,追问的内容会丢吗?
没有定论。有用户在 iPhone 上的 Codex Remote 里看到回合仍显示进行中,并出现 Continue 按钮;也有 Windows 用户反映,回复问题卡片后看不到预期的回答,只剩已执行命令的卡片。重试之前,先把追问的内容复制出来。
用 iPhone 上的 Codex Remote 也会出现吗?
会,已经有人在 Remote 对话里遇到。那位用户连接的 Mac 上,openai_base_url 同样指向 127.0.0.1:4202。要检查和修复的是运行 Codex 的那台电脑,不是手机。
能保留 codex-router,又正常中途追问吗?
能。把 codex-router 更新到包含 PR #1004 的版本即可,这正是修复的目的。更新前想继续用外部模型,就先用 instant_interrupt = false 过渡。
压缩失败之后才开始出现,两者有关系吗?
有 Windows 用户第一次遇到这条报错,是在一次上下文压缩失败之后,但他自己也无法确认两者有因果关系。压缩失败本身怎么处理,见《Codex 远程压缩失败:先看完整报错,再决定重试还是恢复会话》。
没有本机代理也出现这条报错:到 #52221 报告
如果 config.toml 里既没有 openai_base_url,也没有指向本机的自定义 provider,这条报错就超出了已知原因。#52221 中指出 codex-router 原因的评论者也说,没有代理的情况属于另一个原因,issue 应该为此保持打开。
到 openai/codex #52221 补充时,带上这些信息:
- Codex 桌面版或 CLI 的版本号,以及操作系统;
- 出错的时间和时区;
- 是否设置了
openai_base_url或自定义 provider(写“是/否”和主机端口即可); codex features list里instant_interrupt那一行;- 出错前你做了什么:追问、回复问题卡片,还是点了停止。
不要附上凭证、本机代理的完整地址或私人对话内容。
如果你已经更新了 codex-router,报错变成了以 or response.interrupt. 结尾的新文字,问题在 codex-router 这一侧,到它的 issue 区报告更合适。
如果看到的不是这个 400,而是界面反复出现 Reconnecting,那是另一类连接问题,见《Codex 一直 Reconnecting:先保住任务,再定位是哪一层断了》。
自己维护 Responses 网关:同时放行 response.interrupt
如果你自己写或维护一个给 Codex 用的 Responses 代理,这次的教训是:WebSocket 连接上不只会出现 response.create。
- 处理
response.interrupt:字段是response_id和mode: "discard_partial_items",Codex 等的回复是response.interrupt.accepted或response.interrupt.failed。这个事件在公开的 API 指南里没有记载,以 Codex 源码为准。 - 考虑
response.steer:这是 OpenAI 公开文档里的中途引导事件,只用于 GPT-6 系列、只走 WebSocket,被引导的响应以response.incomplete(原因steered)结束。 - 按已知类型校验,不要一律放行:codex-router #1019 期望的做法,是对支持的类型逐一处理,对未知类型返回清楚的错误,同时保证之后的
response.create能在同一条连接上继续。 - 暂时不支持 WebSocket:自定义 provider 可以在
[model_providers.*]里声明supports_websockets = false,让 Codex 改走 HTTPS(Coder AI Gateway 的文档给出了这个办法)。这只适用于自定义 provider;openai_base_url改道的是内置 OpenAI provider,它默认开启 WebSocket。HTTPS 路径下中途引导是否表现一致,公开资料没有说明。
自定义 provider 的写法和逐项验证方法,见《Codex 接第三方模型 API:先确认 Responses 兼容,再写 provider》。



