DeepSeek Harness headless 报 MISSING_CREDENTIAL:凭据查找顺序与配置

故障排查发布于 2026-10-30作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSHheadlessMISSING_CREDENTIAL凭据.env令牌吊销
DeepSeek Harness headless 模式报 MISSING_CREDENTIAL,密钥明明写在 .credentials.yaml 里。从 0.2.1-alpha.3 起 headless 默认不挂载凭据服务,只查启动环境、调用目录 .env 和 ~/.dsh/.env,先判环境再选路径。

密钥就在 ~/.dsh/.credentials.yaml 的 refs 里,值也是内联的真实 key,可 dsh --profile headless "hi" 一秒就退,报 MISSING_CREDENTIAL: llm-pi-ai: no credential for provider route "zai-coding-cn"。 这不是密钥写错了,而是从 0.2.1-alpha.3 起,随包的 headless profile 根本不再挂载凭据服务——它换了整套来源(#11051)。先判环境,再判版本,最后选路径。

DeepSeek Harness 第一步:判环境,桌面端正常不代表 headless 正常

桌面端读凭据库,headless 不读;同一个 key 在两边命运完全不同,先确认你跑的是哪一种。

  1. 看启动命令:带 --profile headless、或以 dsh headless 形式被调度器拉起的,就是 headless。
  2. 看有没有界面:桌面端有 Web UI 和「模型」设置页,headless 只有 stdout 与 NDJSON。
  3. 看报错格式:headless 是 dsh: <CODE>: ... 一行就退,桌面端会在 UI 里给卡片。
  4. 如果你在调度器或 CI 里跑,基本可以按 headless 处理。

这一步的结论只有一个:不要把桌面端「在模型页填了 key 就能用」的经验搬到 headless。

DSH插件 第二步:判版本,0.2.1-alpha.3 是分水岭

这是文档化的设计变更,不是回归:0.2.0-rc.2 能解析存储凭据,0.2.1-alpha.3 起随包 headless profile 禁用了相关服务。

  1. 执行 dsh --version 记录完整版本号。
  2. 低于 0.2.1-alpha.3 的,先按旧行为排查。
  3. 0.2.1-alpha.3 及之后,直接判定为「存储不生效」,别再花时间验证 .credentials.yaml 的格式。
  4. 顺带看一次 profile 的 cordis.patch.yml,里面明确列着 credentials、authorization、deepseek-account 三项为禁用。

社区还观察到 0.2.1 首次 headless 启动会把 .credentials.yaml 重写成 refs/records 结构,所以文件 mtime 变了并不代表你改对了地方。

DeepSeek Harness headless 的凭据查找顺序:只有三处

启动环境 → 调用目录的 .env → Harness home 的 .env,仅此三处;凭据库不在其中。

  1. 第一优先是进程环境变量,也就是你启动那一刻的 env。
  2. 第二是当前工作目录下的 .env。
  3. 第三是 ~/.dsh/.env(或 DSH_HOME 对应的 .env)。
  4. 三处都没有,才抛 MISSING_CREDENTIAL,且失败发生在联系模型端点之前——所以网络、代理、余额都不是原因。
bash
# ~/.dsh/.env(变量名以 profile 的 refs 为准)
ZAI_CODING_CN_API_KEY=sk-xxxxxxxx

社区做过隔离对照:只有存储 key 的 headless 完全不发请求;导出假 key、调用目录 .env、home .env、三行补丁这四种方式都能跑通,mock 也收到了对应 key。对照组里 SDK 与 ACP 只用存储 key 也能通,因为它们的凭据服务是活跃的。

DeepSeek插件 两条可执行路径:写 .env 或恢复服务

最省事的是把 key 写进 ~/.dsh/.env;想继续用凭据库,就按 README 的三行补丁把服务加回来。

  1. 路径 A:在 ~/.dsh/.env 里写一行 ZAI_CODING_CN_API_KEY=<真实 key>,注意变量名要与 profile 里 refs 引用的一致。
  2. 确认文件权限收紧,别留成全局可读。
  3. 重新执行 dsh --profile headless "hi",看是否不再报 MISSING_CREDENTIAL。
  4. 路径 B:打开 packages/bundle/headless/README.md,把文档里的三行恢复补丁加到你的 profile 配置里。
  5. 重启后再跑一次,验证凭据从存储解析成功。
  6. 如果用调度器(例如 LaunchAgent),记得把 key 写进它的 EnvironmentVariables,否则交互式终端能跑、定时任务仍然失败。

社区案例里生产定时任务就是在 10-23 的 07:30 与 09:00 两次失败,最后靠注入调度器环境变量恢复。

DeepSeek Harness 提示文案本身会误导你

MISSING_CREDENTIAL 的文案不区分 plane:它先推荐「存到凭据服务(Web 模型页会写进去)」,而 headless 恰恰不挂载这个服务。

  1. 看源码就知道:解析器先 ctx.get('credentials') 判断服务在不在,再决定查存储还是查启动环境。
  2. 但错误文本是三段拼死的,不随这个判断变化。
  3. 结果就是用户照着第一条建议操作,再撞一次同样的错。
  4. 真正有效的是第三句「在启动环境里 export」——社区指出这一句本来就在,只是被前两句盖住了。
  5. 这条属于诊断文案缺陷,影响级别不高,但不是「凭据丢失」,也没有越权风险。

DSH插件 附带场景:全局吊销浏览器会话令牌

桌面 Web 端的浏览器 cookie 能跨普通重启存活,要全局吊销只能删 client-connection/browser-session 这一条记录再重启。

  1. 完全停止所有使用同一 home 的 Harness 进程。
  2. 备份 .credentials.yaml(默认 %USERPROFILE%\.dsh\.credentials.yaml;改了 DSH_HOME 就用实际路径)。
  3. 在 records 下只删除 client-connection/browser-session 键和它的整个值,保留 version、refs 与其他 records;如果它是最后一条,留 records: {}。
  4. 重启 Harness,用新生成的启动 URL 重新登录。
  5. 验证:用旧 cookie、去掉 ?token=、保持相同 scheme/host/port 请求,应返回 401。
  6. 再用新启动 URL 请求应返回 303,其新 cookie 认证应返回 200。

这里有个坑:authority 必须完全一致。换了主机名或端口,cookie 本来就会失效,你会误以为吊销成功了。社区在隔离环境里验证过:普通重启旧 cookie 仍有效,删掉那条记录再重启才被拒。

注意事项

  1. 别只改 .credentials.yaml 就期待 headless 生效。它读的是 .env 与环境变量。
  2. 别把 SDK / ACP 的表现当参照。它们的凭据服务是活跃的,提示对它们适用。
  3. 别忽略调度器环境。交互式终端能跑不等于定时任务能跑。
  4. 吊销令牌别删整份凭据文件。只删那一条记录,其他引用不受影响。
  5. 记录版本号。这是判断「设计变更还是缺陷」的唯一依据。

如果你的报错码不是 MISSING_CREDENTIAL 而是 401/403,那是另一条链路,先查凭据内容与账号状态。相关排查见 DeepSeek Harness 配置 API Key 报错:MISSING_CREDENTIAL 与 UNKNOWN_MODEL 的排查与解决。

常见问题

headless 模式下 .credentials.yaml 里明明有 key,为什么 DeepSeek Harness 还报 MISSING_CREDENTIAL?

因为 DeepSeek Harness 随包的 headless profile 把 credentials、authorization、deepseek-account 三个服务都禁用了,存储型凭据根本不会被读。它只查启动环境、调用目录的 .env 和 ~/.dsh/.env,所以把 key 放进 ~/.dsh/.env 才有效。

从哪个版本开始,DeepSeek Harness 的 headless 不再读凭据库?

DeepSeek Harness 的这个分界是 0.2.1-alpha.3,按社区回复是文档化的变更,不是回归。0.2.0-rc.2 上同样的配置能解析成功,升级后就只剩启动环境这一条路。

MISSING_CREDENTIAL 的提示让我存到凭据服务,为什么在 DeepSeek Harness 里照做还是失败?

因为 DeepSeek Harness 的提示文案没有按 plane 分支。代码里已经用 ctx.get('credentials') 判断服务在不在,文案却还在推荐一个 headless 没挂载的服务;真正有效的第三句是「在启动环境里 export」。

不想改 profile 时,怎么在 DeepSeek Harness 中恢复存储型凭据?

按 DeepSeek Harness 随包的 packages/bundle/headless/README.md 里的三行补丁把凭据相关服务加回来。社区核对的可行来源有四个:export 环境变量、调用目录 .env、~/.dsh/.env、三行恢复补丁。

浏览器会话 cookie 怎么全局吊销,DeepSeek Harness 的 UI 里找不到入口怎么办?

先停掉所有 DeepSeek Harness 进程,备份 .credentials.yaml,在 records 下只删 client-connection/browser-session,再重启。之后用旧 cookie 但去掉 ?token= 请求同一 authority,应返回 401。

相关术语

MISSING_CREDENTIAL
MISSING_CREDENTIAL 是 DeepSeek Harness 在解析不到模型凭据时返回的错误码,headless 下会以 exit 1 秒败。它表示凭据来源在当前组合里不可用,而不是密钥内容错误。— https://github.com/deepseek-ai/deepseek-harness/discussions/11051
headless profile
headless profile 是 DeepSeek Harness 随包提供的无界面运行 profile,其 cordis.patch.yml 默认禁用 credentials、authorization 与 deepseek-account 三个服务。凭据只能来自启动环境或 .env 文件。— https://github.com/deepseek-ai/deepseek-harness/discussions/10609
launch environment
launch environment 是启动 dsh 进程时继承的环境变量集合,是 headless 下优先级最高的凭据来源。它排在调用目录 .env 与 Harness home .env 之前。— https://github.com/deepseek-ai/deepseek-harness/discussions/10609
client-connection/browser-session
client-connection/browser-session 是本地凭据库中保存浏览器会话令牌的记录键。删除该记录并重启可全局吊销已发放的会话 cookie,其他凭据记录不受影响。— https://github.com/deepseek-ai/deepseek-harness/discussions/10915

来源