codex 问题排查记录

代理端口:

1
2
3
mixed-port: 7897     # HTTP + SOCKS 混合端口
socks-port: 7898
port: 7899 # 纯 HTTP

一、首次启动 reconnecting 5 次

现象:每次启动都要重连 5 次才连上,诊断命令里是这两行:

1
2
⚠ websocket    Responses WebSocket failed; HTTPS fallback may still work
✗ reachability one or more required provider endpoints are unreachable over HTTP

最终能降级到 HTTPS 跑起来,所以表现是”慢”而不是”挂”。

根因:Windows 的「系统代理」(注册表 Internet Settings)只对主动去读它的程序生效。codex 的普通 HTTP 请求会读它,所以连通性探测是通的;但 WebSocket 客户端不读,于是直连超时、重连 5 次。

请求类型 是否读系统代理 结果
普通 HTTP(探测、降级后的 HTTPS) 读 通
WebSocket 客户端 不读 超时 → 重连 5 次

也就是说,「系统代理开着」对 WebSocket 完全无效,这是必然结果,不是配置没生效。

Clash 侧不需要任何额外配置:WebSocket 握手本质是一次带 Upgrade: websocket 头的 HTTP 请求,经 HTTP 代理走 CONNECT 隧道,隧道是纯字节流,Clash 不解析里面跑的是 HTTP 还是 WebSocket,没有开关要打开。

解决:WebSocket 客户端认环境变量,指向 Clash 的混合端口。

1
2
3
setx HTTP_PROXY  "http://127.0.0.1:7897"
setx HTTPS_PROXY "http://127.0.0.1:7897"
setx NO_PROXY "localhost,127.0.0.1,::1"
  • wss:// 走 HTTPS_PROXY;NO_PROXY 让回环地址直连。
  • setx 写的是用户级变量,对已打开的窗口不生效,终端要整个退出重开(新开标签页不够)。
  • 少数工具只认小写变量名,不生效就再补一组小写的 http_proxy / https_proxy。

环境变量是全局的,副作用是代理软件没开时其他程序不会自动回退直连——实测返回 000(退出码 7)。只对单条命令注入的做法:

withproxy.cmd

1
2
3
4
5
6
7
8
9
@echo off
setlocal
set "HTTP_PROXY=http://127.0.0.1:7897"
set "HTTPS_PROXY=http://127.0.0.1:7897"
set "http_proxy=http://127.0.0.1:7897"
set "https_proxy=http://127.0.0.1:7897"
set "NO_PROXY=localhost,127.0.0.1,::1"
set "no_proxy=localhost,127.0.0.1,::1"
call %*

用法就是 withproxy codex。

  • 最后一行必须是 call %*,不能写成 %*。不加 call 时控制权不返回本脚本,两边 setlocal / endlocal 的配对被打乱,刚设的变量会被一起弹掉,等于没注入。
  • 文件要存成 CRLF 换行 + 纯 ASCII。

验证:

1
2
✓ websocket    connected (HTTP 101 Switching Protocols) · 15s timeout
✓ reachability active provider endpoints are reachable over HTTP

HTTP 101 Switching Protocols 是 WebSocket 握手成功才会有的状态码。

二、无法在提权终端启动后台 daemon

现象:启动时报错,大意是检测到当前运行在提权(elevated)终端里,拒绝启动后台 daemon。

根因:不在 codex,在 Windows 的 UAC。EnableLUA 为 0(UAC 关闭)时,系统不再做令牌过滤,进程拿到的都是完整的管理员令牌——Administrators 组(S-1-5-32-544)在里面且处于启用状态。codex 检查的正是这一项(GetTokenInformation + CheckTokenMembership),于是无论终端是不是”以管理员身份运行”都判定为提权,结果就是它认为你永远在提权终端里。

而 daemon 是一个常驻的本地服务,其他 codex 进程连上它就能让它代为执行命令。把它跑在管理员权限下,等于在后台挂了一个管理员权限的执行器,所以 codex 选择直接拒绝启动。

1
2
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
EnableLUA = 0

解决:在 ~/.codex/config.toml 末尾关掉 daemon 自动启动。

1
2
[features]
daemon_auto_start = false
  • codex features list 可以确认这项当前是 false。
  • 代价是依赖共享 daemon 的命令(如 codex agents)不可用。
  • 临时绕过:codex --no-daemon。
  • 要恢复 daemon 的完整功能,只能把 EnableLUA 改回 1 并重启。