Codex 桌面端 "Unable to load sign-in requirements":config.toml 解析失败实录
不是网络、不是代理、不是登录凭证——是 config.toml 被写坏了。CodexManager 的配置切换把 model_provider = "..." 追加到文件末尾,而末尾残留着 [model_providers] 裸表头,这一行于是被解析成该表的字段,类型不对 → 整个配置文件解析失败 → Codex 回退默认配置 → 登录要求加载不出来。
01现象
Codex 桌面端启动后停在登录页,提示 Unable to load sign-in requirements,界面上只有一个 Retry 按钮。当天 20:55 之后首次出现,重试无效。
| 项目 | 内容 |
|---|---|
| 影响组件 | OpenAI Codex 桌面端(26.917.71314)、CodexManager 配置切换功能 |
| 首次出现 | 2026-09-25 20:55 之后 |
| 表现 | 登录页卡死,仅 Retry,重试无效 |
02排查:三个常见怀疑点全部排除
登录类报错的第一反应通常是网络或凭证,这次三个都不是:
| 怀疑点 | 结论 | 依据 |
|---|---|---|
| 网络不通 | 排除 | curl 直连 auth.openai.com 返回 200;chatgpt.com / api.openai.com 均有正常 HTTP 响应(403/401 属于预期) |
| 代理失效 | 排除(无影响) | 系统代理本就处于禁用状态(ProxyEnable=0);配置的 43.154.176.228:1080 虽已不可达,但未被任何组件使用 |
| 登录凭证失效 | 排除 | auth.json 内 token 有效期至 2026-10-05,当天 21:34 刚成功刷新;修复后 codex login status 返回 Logged in using ChatGPT |
三个「看起来最像」的原因都被证据否掉之后,剩下的方向只有本地配置本身。这类问题看日志比猜要快——日志里已经有明确的行号和类型错误。
03根因:一行写错了位置
CodexManager 的配置切换逻辑(go/internal/server/codex_profile.go 中的 patchGatewayConfig / patchDirectConfig)把 model_provider = "..." 追加到 config.toml 文件末尾。
问题在于:文件末尾残留着一个 [model_providers] 裸表头。按 TOML 语法,表头之后的所有键值都归属于该表,于是追加进去的那一行实际变成了:
[model_providers]
model_provider = "openai" # ← 被解析为 model_providers.model_provider,类型错误
model_providers 表内只允许 provider 结构体,不接受字符串。于是整个 config.toml 解析失败,Codex 回退到默认配置,登录要求自然加载不出来。
04日志证据
来自 ~/.codex/logs_2.sqlite,当天共 16 条同类错误,关键两条:
20:55:26 config.toml:225:18: invalid type: string "cm", expected struct ModelProviderInfo # 切换到 cm 中转
21:34:37 config.toml:225:18: invalid type: string "openai", expected struct ModelProviderInfo # 切回 openai
两次切换(cm ↔ openai)都把该行写进了错误位置,所以来回切换并不能自愈,只会继续写坏。
05两步修复
- 配置层:删掉误入的行删除
~/.codex/config.toml中误入[model_providers]表内的model_provider行(改动前先备份为config.toml.bak-20260925-beforefix)。删除后 TOML 解析通过,用codex login status验证恢复。 - 工具层:从机制上杜绝
patchDirectConfig/patchGatewayConfig改为把model_provider前置到文件最顶部(任何表头之前),这样它永远不可能落进某个表内。go build通过,TestCodexProfileDirectApplyAndRestore/TestCodexProfileGatewayApplyAndRestore等相关测试全部通过。
06嫌手动改麻烦?用 Trae Work + GLM-5.3 直接让它修
上面两步要自己找文件、备份、删行、再跑命令验证,手生的话容易改错。更省事的办法是把报错截图直接丢给 AI 让它动手——用 Trae Work(Trae 的 Work 模式),模型选 GLM-5.3,它会自己打开 ~/.codex/config.toml 定位问题行、备份、删除并跑 codex login status 验证。
- 截图报错界面把 Codex 桌面端那个
Unable to load sign-in requirements提示框截下来(带上 Retry 按钮)。 - 丢进 Trae Work,选 GLM-5.3新建会话,模型切到 GLM-5.3,粘贴截图,配上下面的提示词。
- 让它改完自己验证它会读
~/.codex/config.toml、找出误入[model_providers]表内的model_provider行、先备份再删除,最后跑codex login status确认恢复。你只要看它给的结果。
这类问题的排查路径很固定:看日志 → 定位行号 → 备份 → 删行 → 命令验证。GLM-5.3 在 Trae Work 里可以直接操作本机文件、跑终端命令,比人肉翻 ~/.codex 目录快得多,也不容易漏掉备份那一步。
AI 能修好配置文件,但修不了工具层的 bug。前面说过,正在运行的 CodexManager 二进制还是旧逻辑,重新编译之前别再用它切换账号,否则会被再次写坏——这一点 AI 帮不了你,得等你重新 build。
07注意事项
当前机器上正在运行的 CodexManager 二进制仍是旧逻辑(顶层那行 model_provider 在 21:34 的切换中未被清理,就是佐证)。重新编译(build-go.ps1)之前不要再用它切换账号,否则会再次写坏配置。
- 如果再次出现同一报错,先看
~/.codex/logs_2.sqlite里有没有invalid type: string ..., expected struct ModelProviderInfo,有就是同一个坑。 model_provider这类顶层键必须写在任何表头之前,这是 TOML 的基本规则,写配置生成逻辑时最容易踩。TestAccountRPCContract测试失败(account/create返回403 management_local_only)与本次问题无关,属历史遗留。
相关阅读:《Codex Windows 沙盒设置失败:改成 unelevated 即可恢复》|《Codex 风控为何越来越严》|《Codex 接入 typesafe-ai 实战》
本文为 2026-09-25 本机故障排查实录,涉及版本号、行号与 IP 均为当时环境实测值。
