来源: #636 (#636 ) 分析用户「升级到 0.1.95 后 codex 仍报 mcp_servers.bili.args expected a sequence」时发现
现象
用户 ~/.codex/config.toml 里存在一个 [mcp_servers.bili] 块,其中 args 被写成了字符串 (整个列表被一对引号包住),例如:
[mcp_servers .bili ]
command = " node"
args = ' ["C:\Users\<you>\AppData\Roaming\npm\node_modules\billion-context\dist\mcp.js"]'
env = { BILI_MCP_PROXY = " http://127.0.0.1:8787" }
这是合法 TOML (能 parse),但 codex 的 schema 要求 args 是数组(sequence),于是启动时报:
Error loading config.toml: invalid type: string "[...]", expected a sequence in `mcp_servers.bili.args`
问题(bug)
src/plugin-install.ts 的 codexInstall()(v0.1.95)在块已存在时,用只比对 BILI_MCP_PROXY 那一行 来判断是否「已安装」:
if ( block . includes ( `BILI_MCP_PROXY = ${ JSON . stringify ( proxyOriginForInstall ( ) ) } ` ) ) return `codex: already installed (${ file } )` ;
只要 env 行匹配当前 origin,就直接返回 already installed,完全不校验 / 修复 args(以及 command) 。因此:
升级 bili 后重新 bili plugin install codex → 命中 already installed → 畸形 args 原样保留 → codex 依旧报错。
只有 bili plugin remove codex(纯文本切片删除,不看内容)+ 重新 install 才能修好。
也就是说,「升级 / 重装」这条用户最自然的自愈路径,对这种畸形块是无效 的。
复现(v0.1.95 逻辑,零依赖)
往 config.toml 写入上面那个畸形块(env 行 = 默认 origin,args = 字符串)。
运行 bili plugin install codex → 输出 codex: already installed (...),args 行未变 (仍是字符串)。
运行 bili plugin remove codex,再 bili plugin install codex → args 变为合法数组 ["…"],codex 正常。
已用 v0.1.95 的 codexInstall / codexRemove 原文 + 少量 stub 实际跑过,确认第 2 步不修复、第 3 步修复。
影响
用户被卡住:升级 / 重装都自愈不了;且报错是 codex 的 serde 类型错误,完全没指向 「config.toml 里 args 写成了字符串」,排查困难(疑似字符串错误 #636 就卡在这里)。
plugin install 作为「安装 / 刷新」命令,在块已存在但畸形时静默 no-op,违背直觉。
建议修复
把「已安装」判定从「只比对 origin 行」改为「整块与规范块比对」:只有当现有块与 codexBlock() 生成的规范块一致时才返回 already installed,否则一律用规范块替换(自愈 args / command / 路径)。最简实现:块存在时直接以 codexBlock() 覆盖(内容确定、天然幂等),仅在字节一致时保留 already installed 文案。
顺带:codexInstall 命中畸形块时,可打印一句更明确的提示(如「检测到 [mcp_servers.bili].args 不是数组,已重写」),而不是让用户去啃 codex 的 serde 报错。
来源: #636 (#636) 分析用户「升级到 0.1.95 后 codex 仍报
mcp_servers.bili.argsexpected a sequence」时发现现象
用户
~/.codex/config.toml里存在一个[mcp_servers.bili]块,其中args被写成了字符串(整个列表被一对引号包住),例如:这是合法 TOML(能 parse),但 codex 的 schema 要求
args是数组(sequence),于是启动时报:问题(bug)
src/plugin-install.ts的codexInstall()(v0.1.95)在块已存在时,用只比对BILI_MCP_PROXY那一行来判断是否「已安装」:只要
env行匹配当前 origin,就直接返回already installed,完全不校验 / 修复args(以及command)。因此:bili plugin install codex→ 命中already installed→ 畸形args原样保留 → codex 依旧报错。bili plugin remove codex(纯文本切片删除,不看内容)+ 重新install才能修好。也就是说,「升级 / 重装」这条用户最自然的自愈路径,对这种畸形块是无效的。
复现(v0.1.95 逻辑,零依赖)
config.toml写入上面那个畸形块(env行 = 默认 origin,args= 字符串)。bili plugin install codex→ 输出codex: already installed (...),args行未变(仍是字符串)。bili plugin remove codex,再bili plugin install codex→args变为合法数组["…"],codex 正常。已用 v0.1.95 的
codexInstall/codexRemove原文 + 少量 stub 实际跑过,确认第 2 步不修复、第 3 步修复。影响
args写成了字符串」,排查困难(疑似字符串错误 #636 就卡在这里)。plugin install作为「安装 / 刷新」命令,在块已存在但畸形时静默 no-op,违背直觉。建议修复
把「已安装」判定从「只比对 origin 行」改为「整块与规范块比对」:只有当现有块与
codexBlock()生成的规范块一致时才返回already installed,否则一律用规范块替换(自愈args/command/ 路径)。最简实现:块存在时直接以codexBlock()覆盖(内容确定、天然幂等),仅在字节一致时保留already installed文案。顺带:
codexInstall命中畸形块时,可打印一句更明确的提示(如「检测到[mcp_servers.bili].args不是数组,已重写」),而不是让用户去啃 codex 的 serde 报错。