Repository navigation
Open
Labels
priority: P2普通优先级普通优先级
Description
环境
- OS:Windows 11(10.0.26200 x64)
- ZCode Desktop:3.18.2.10443(2026-11-13 16:44 自动升级,升级前版本正常)
- 外部 ACP 客户端:hifox,通过
node zcode.cjs app-server --stdio拉起 headless 会话 - 模型通道:
account:bigmodel-individual-coding-plan→https://open.bigmodel.cn/api/anthropic(SSE)
一句话结论
升级把凭证存储切换为 OS 凭据库加密(enc:v2 / credential-source: os)后,桌面端进程能解密、一切正常;外部客户端用裸 node 拉起的 headless app-server 解不出凭证,请求不带有效 token 出网 → 服务端恒定 401 auth_failed,token 刷新通道同样失败,表现为一发即死、不重试。同一份凭证文件、同一端点,桌面端在故障窗口内正常工作,可证明凭证本身有效。
复现步骤
- ZCode Desktop 升级到 3.18.2.10443(2026-11-13 16:44)
- 外部 ACP 客户端按常规方式拉起 headless app-server 并触发一次对话
- 观察模型请求 → 401;同时在桌面端发起新对话 → 正常
时间线(2026-11-13,本地时间 UTC+8)
| 时间 | 事件 |
|---|---|
| 16:44 | 升级安装:~/.zcode/v2/credential-source 重写为 os |
| 17:07–17:08 | 桌面端重启;~/.zcode/v2/credentials.json 全量重写为 enc:v2: 加密条目 |
| 17:10:36 | headless/ACP 路径首次出现 401(当天此前 0 次) |
| 17:10–17:53 | hifox 会话持续 401(84 条失败记录);桌面端同时段正常 |
| 17:53:51 | hifox 新建会话,headless app-server 全新进程拉起 |
| 17:53:57 / 17:53:59 | 新进程两次 401(读的就是 17:08 重写后的新凭证文件) |
| 17:37 / 全天 | 桌面端同端点成功流式 3316 次 |
证据
A. 同端点、同凭证:桌面端成功,headless 401(时间窗重叠)
- 401 全部来自
https://open.bigmodel.cn/api/anthropic,与桌面端成功请求的端点完全相同 - 401 窗口(17:10:36–17:53:59)内,桌面端完成 18 次成功补全(首条 17:37:59、末条 17:45:32,均为
ttft.model.completed) - 401 窗口结束后,桌面端 18:04:08 继续正常补全——凭证在整个故障期内有效
B. 排除"旧进程持有旧 token":全新进程仍然 401
17:53:51 由 hifox 全新拉起的 headless 进程(启动仅 6 秒,读取的是 17:08 重写后的新凭证文件),17:53:57 即 401:
{"timestamp":"2026-11-13T09:53:57.865Z","event":"model.request.failed",
"context":{"providerId":"account:bigmodel-individual-coding-plan","modelId":"GLM-5.3",
"attempt":1,"maxAttempts":11,"transport":"sse","reason":"auth_failed",
"retryable":false,"statusCode":401,"statusMessage":"Provider authentication failed."}}C. 凭证刷新通道同样不可用
{"timestamp":"2026-11-13T09:53:57.868Z","event":"model.retry.delay.resolved",
"context":{"reason":"auth_failed","retryReason":"auth_refresh","statusCode":401}}retryable: false + 刷新立即失败 → headless 无法通过刷新获得新 token,与"无法解密存储中的 refresh token"一致。
D. 两种 app-server 的启动拓扑差异(疑点所在)
| 桌面端(正常) | headless/ACP(401) | |
|---|---|---|
| 拉起方式 | ZCode.exe → zcode-runtime-host.exe(命名管道宿主)→ zcode.cjs app-server --stdio --surface desktop |
hifox daemon → zcode-acp.cjs server → 裸 node.exe 直接运行 zcode.cjs app-server --stdio(无 runtime-host) |
| 结果 | 全天正常 | 全部 401 |
E. 升级前无此问题
- 2026-11-12 全天日志:0 条 401;ACP 路径仅有一次无关错误码(
IDENTITY_VERIFICATION_REQUIRED) - 401 起点(17:10:36)= 升级 + 凭证重加密完成(17:08)之后 ACP 的第一次对话
F. 凭证存储形态(升级引入的变化)
credential-source内容:os(16:44 写入)credentials.json所有条目为enc:v2:...形态(17:08 重写),键含zcodejwttoken、oauth:zai_cn:access_token、oauth:linked_bigmodel等- 桌面端可正常使用这些凭证发起请求,说明凭证内容有效;headless 侧表现为"有存储但用不了"
推测的根因
OS 凭据库作用域的加密凭证(enc:v2 / credential-source: os)在 Electron 主进程之外不可解密(或解密/刷新通道依赖 runtime-host),headless app-server 读到密文后无法还原,也未走"回退到其他凭证源"的路径,导致不带有效 Authorization 出网。
期望行为
headless / ACP 拉起的 app-server 应与桌面端一致地解密(或刷新)凭证;若无法解密,应给出明确错误(如"凭证解密失败")而非让请求裸发出网拿到 401。
当前 workaround(已验证思路)
为 headless 场景配置 API key 型 provider(绕开 OS 加密凭证)后 ACP 可用;但官方对 OAuth 凭证在 headless 下的支持仍期望修复。
附注
- 以上日志行号(如
model.request.failed位于zcode-2026-11-13.jsonl第 27791 行)对应本地日志文件,需要完整片段可提供 - 已排查并排除的方向:provider ID 映射错误(升级后已正确映射到新 ID)、模型权限(GLM-5.3 与 GLM-5.3-Flash 在故障窗口前后均有成功记录)、端点差异(两条路径端点相同)、凭证过期(桌面端同时段正常)
Metadata
Metadata
Assignees
Labels
priority: P2普通优先级普通优先级
Activity
github-actions commentedon Nov 13, 2026
👋 感谢你的反馈,我们已经收到。
status: 待评估,你可以随时补充信息。needs: 更多信息标签并 @ 你。👋 Thanks — we've received your issue.
status: 待评估(Triage); feel free to add context.needs: 更多信息and ping you.