复盘笔记:cc-switch 切换供应商报「账号不存在」的排查与修复
日期:2026-09-12
环境:Windows 11 Pro 22631 / CC Switch v3.20.1 / Codex CLI(ChatGPT OAuth 登录)
结果:已修复,可正常切换供应商;Codex 官方登录恢复正常
1. 问题现象
在 cc-switch 的 Codex 页签里,只要从「OpenAI Official」切换到任何其他供应商,就报错:
切换失败:账号不存在: b01f1e34-8c39-4444-ad65-1c6d1ab0a92b「OpenAI Official」这张卡片处于"锁死"状态,编辑后无法保存,同样报账号不存在。
关闭设置里的「切换供应商时保留 Codex 官方登录」没有任何效果。
额外发现:
~/.codex/auth.json文件根本不存在,也就是说 Codex CLI 本身也处于未登录状态。
通俗解释:cc-switch 相当于一个"账号管家",帮你在多个供应商之间切换。它手里有一张卡片(OpenAI Official)写着"这张卡对应 X 号账号",但 X 号账号已经被注销了,管家每次想动这张卡都先去找 X 号账号,找不到就直接罢工,连带着其他卡片也换不了。
2. 排查过程
2.1 涉及的文件
2.2 关键发现
账号库里的账号(codex_oauth_auth.json):
报错里的 b01f1e34-… 不在账号库里——它是旧的、已经被删除的记录。
数据库里的绑定(providers 表,id = 'codex-official' 那一行的 meta 字段):
"authBinding": {
"source": "managed_account",
"authProvider": "codex_oauth",
"accountId": "b01f1e34-8c39-4444-ad65-1c6d1ab0a92b"
}卡片仍然绑着已不存在的旧 ID,这就是"悬空引用"。
2.3 根因
最初导入的账号会话过期,重新认证了同一个 ChatGPT 用户。
cc-switch v3.20.1 重新认证时不会更新原记录,而是新建一条记录、分配一个新的 UUID。
「OpenAI Official」卡片的绑定没有跟着更新,依旧指向旧 UUID。
cc-switch 切换供应商的流程里,只要"当前卡片"或"目标卡片"是托管账号卡,就要先按绑定的 ID 去账号库取凭据;取不到就抛
AccountNotFound,整个切换在提交之前就失败了。因为当前卡片正是这张坏卡,所以连"切走"都做不到,也不允许直接删除当前卡,UI 里没有任何恢复路径。
通俗解释:你换了新手机号,但通讯录里存的还是旧号码。问题在于 cc-switch 打电话之前必须先核对通讯录,核对不通就拒绝做任何事,包括"换一个人打"。
这是 cc-switch 的已知 bug:
GitHub issue #7055(删除并重新添加托管账号后绑定悬空)——与本次情况完全一致,截至 2026-09-12 仍为 open(未解决)
GitHub issue #6969(v3.20.0 → v3.20.1 升级时 ID 主键变更未迁移)——同症状的另一条触发路径,仍为 open
PR #7061(拒绝重复添加同一托管账号)已于 2026-09-03 合并,只能防止今后再产生重复记录,不会修复已经悬空的绑定
3. 修复方案
3.1 采用的方案:手动修改数据库绑定
思路:把 codex-official 的 authBinding.accountId 从旧 UUID 改成账号库里现存的新 UUID。
前提:必须先完全退出 cc-switch(注意它默认"关闭时最小化到托盘",点 × 不算退出,要在托盘右键退出,或用 taskkill /F /IM cc-switch.exe)。原因是运行中的程序可能缓存数据并把修改覆盖回去,也可能产生文件锁冲突。
步骤:
备份
~/.cc-switch/cc-switch.db和~/.cc-switch/codex_oauth_auth.json。执行 SQL(等价写法):
UPDATE providers SET meta = replace(meta, 'b01f1e34-8c39-4444-ad65-1c6d1ab0a92b', '9a8a9a6c-860f-47a5-9bed-93aabfbfaee9') WHERE id = 'codex-official' AND app_type = 'codex';本次使用了脚本
E:\html\fix_ccswitch.py(自动备份 → 打印修改前 → 执行 → 打印修改后 → 校验),运行方式:python E:\html\fix_ccswitch.py。重新启动 cc-switch,在 Codex 页签点一下「OpenAI Official」让它重新应用(这一步会用新账号刷新令牌并写回
~/.codex/auth.json)。切换到任意其他供应商验证不再报错。
验证结果:~/.codex/auth.json 已生成,account_id 指向新账号;config.toml 中 model_provider = "cc-switch-official";切换供应商恢复正常。
3.2 备选方案(未采用或无效)
3.3 回滚方法
退出 cc-switch,把备份文件复制回 ~/.cc-switch/cc-switch.db 覆盖即可。
4. 关于 token 有效期的知识(本机实测)
Codex CLI 的策略:
last_refresh超过 8 天就用refresh_token换一套新令牌。所以正常使用下会自动续期,不需要定期"打卡"防过期。真正危险的是 refresh_token 的一次性(轮换)机制:每次刷新都会发一个新的 refresh_token,旧的立即作废。如果同一账号的凭据被复制到两个地方(另一台电脑、另一个 Codex 账号切换工具、手动复制的
auth.json),谁先刷新谁赢,另一份马上失效,报错通常是refresh_token_reused,看起来就像"过期了"。
通俗解释:refresh_token 像一张"一次性换票凭证",用一次就换一张新的。如果你把同一张凭证复印给两个人,第一个人用掉之后,第二个人手里的复印件就作废了。
5. 经验教训与预防措施
一个账号只让一个工具持有凭据。 只通过 cc-switch 登录和管理 OpenAI 账号,不要再单独跑
codex login,不要把auth.json复制到其他机器或工具。重新认证同一账号后,立刻检查官方卡片的账号绑定,看是否还指向旧记录;有条件的话先删旧账号、再添加、再重新绑定。
改数据库前先退出程序、先备份。 cc-switch 的
backups/目录也有自动备份可兜底。遇到"账号不存在: <UUID>",先对比两处:
codex_oauth_auth.json里现存的account_id和providers.meta.authBinding.accountId,两者对不上就是悬空绑定。报 bug 前先搜已有 issue。这次的问题已有 #7055 / #6969 在追踪,新开会被判重复;正确做法是在已有 issue 下补充自己的复现环境。
及时升级:当前最新版为 v3.20.3(2026-09-11 发布),虽然未明确修复悬空绑定,但包含多处托管账号相关修复。等 #7055 关闭后升级即可不再需要手动改库。
注意套餐限制:两个账号都是 free 套餐,若之后出现 429 / 额度用尽类错误,那是配额问题,不要再往登录状态上怀疑。
不要把令牌贴到公开场合:提交 issue 或求助时只贴 UUID,不要贴
codex_oauth_auth.json/auth.json内容。
6. 附带发现(与本问题无关但值得记录)
Claude Code 的 auto 权限模式会调用一个
claude-opus-4-8分类器模型做安全检查。当前 Claude 供应商网关(anyrouter.top)不支持这个模型,返回claude-opus-4-6 已下线,请切换到 claude-opus-4-7,导致 Bash 命令间歇性提示 "auto mode cannot determine the safety"。解决办法:换用支持完整模型列表的供应商,或不使用 auto 模式。~/.codex/config.toml中明文存放了 GitHub PAT 和 Tavily API Key(在 MCP 服务器的 env 里)。分享配置文件前务必脱敏。
7. 参考链接
cc-switch 仓库:https://github.com/farion1231/cc-switch
Issue #7055(本次问题):https://github.com/farion1231/cc-switch/issues/7055
Issue #6969(同症状另一路径):https://github.com/farion1231/cc-switch/issues/6969
PR #7061(部分修复,已合并):https://github.com/farion1231/cc-switch/pull/7061
最新版本发布页:https://github.com/farion1231/cc-switch/releases/tag/v3.20.3
本文为个人学习记录,转载请注明出处:[万俟季先生的个人博客](https://miloaether.loc.cc)