
v8.0.51 上一条被禁用的 Codex 凭证能让中转进程空转烧到 190% CPU,本文给出三分钟确认方法、四步处置与两处顺手能收的口子。
disabled 的 Codex 凭证能让整个中转进程在空闲时烧到 150–190% CPU。触发条件是三个同时成立:refresh token 已被上游终局拒绝、access token 还没过期、而它已经进入 96 小时的提前刷新窗口1。disabled 的 Codex 凭证中招,active 的不会。代价是 CPU,外加最长 96 小时——刷新循环会一直自转,直到 access token 真的过期。auto-refresh scheduler due auths: 1。报障人就是靠这一行在线上认出来的1。GET /v0/management/auth-files,隔几秒再读一次。中招那条的 updated_at 每次都在变,其他条目不动。sdk/cliproxy/auth 里。else if isDisabled 分支,把下次刷新时间写成 now + refreshFailureBackoff,而 refreshFailureBackoff 是 5 分钟2。
else if isDisabled 写 NextRefreshAfter = now.Add(refreshFailureBackoff),并把 shouldReschedule 置真2refreshAuthForRequestAtEpoch 认到「refresh token 没换过、且已被终局拒绝」,又看到 access token 还有效,直接返回一句 refresh token requires sign-in,一个字段都不改4。nextRefreshCheckAt 算。NextRefreshAfter 是零,于是走到提前量分支:dueAt = expiry - lead,一旦不晚于现在,直接返回 now6。
dueAt 就落在过去,返回 now, true7Generation 涨了 83940 次,同一时间里上游刷新调用只有 1 次1。它不花上游额度,只烧 CPU。refreshIneffectiveBackoff(30 秒)只在刷新返回成功、凭证却没变化时才用8。这条走的是 error 返回,所以它管不到。terminalRefresh 那一支——access token 还有效、refresh grant 被终局拒绝,但凭证是 active 的——把 NextRefreshAfter 设成 access token 的到期时刻,然后挂住9。
current.NextRefreshAfter = exp9isDisabled && invalidGrant 那一支更干脆,直接 unschedule,连下次时间都不留10。invalid_grant 这几个字,落进 1446 行的 5 分钟分支。它既没被挂到过期时刻,也没被 unschedule。
codexAutoRefreshUnavailable 只判 refresh_token 是否存在,存在就返回 false(即视为可刷);被拒绝的 refresh token 仍然是「存在」12Disabled: true 正是这条循环的触发条件。authHasUnchangedRejectedRefreshToken 会返回 false,第三步那条提前返回不再成立,循环自然停4。os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0o600)16。break,文件连打开都没有,权限自然也不会被碰。
O_TRUNC 那句(0600 不生效),内容没变则直接 break;只有新建文件那条(第 152 行)才真的写出 060016chmod 600 auth-dir/*.json。新建的文件本来就是 0600,需要改的只有历史遗留。github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
status.openai.com
status.anthropic.com
status.cloud.google.com
codex-reset.com
codex-reset.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.