OpenClaw 自定义 Provider 在 pi-ai 0.63+ 后可能集体失效:明明配了 `apiKey`,为什么还会报 ‘No API key for provider’
OpenClaw News Editorial
一条新的 OpenClaw 回归问题,指向了一个对生产环境很伤的故障模式:自定义 OpenAI 兼容 Provider 会在真正发起请求时直接失败,即使它的 API Key 明明已经正确配置。
表面错误非常直接:
Error: No API key for provider: <name>
但根据 issue 描述,问题并不是“配置里根本没写 key”。相反,key 在前面的链路里其实还能被解析出来,真正断掉的是后面的流式调用交接阶段。
来源:
- OpenClaw issue: openclaw/openclaw#61429
- 相关上游问题: badlogic/pi-mono#2847
当前到底坏在哪里
按 issue 描述,受影响的是这类配置:你在 models.providers.<name> 里定义了一个自定义 Provider,通常包含下面这些字段:
baseUrlapiKeyapi: "openai-completions"- 一组自定义模型 id
报告里的简化示例如下:
{
"models": {
"providers": {
"my-proxy": {
"baseUrl": "http://my-proxy/v1",
"apiKey": "sk-my-key",
"api": "openai-completions",
"models": [{ "id": "my-model", "name": "my-model" }]
}
}
},
"agents": {
"defaults": {
"model": { "primary": "my-proxy/my-model" }
}
}
}
在这次被报告的故障模式里,链路大致是这样:
- OpenClaw 可以正常启动
- 自定义 Provider 看起来也配置正确
- 真正发起一次模型请求
- 请求在 stream 阶段报
No API key for provider: my-proxy
这说明它 不是启动阶段的 schema 校验问题,而是运行时 auth 交接问题。
为什么这事很严重
这不是一个“只有少数极客会遇到”的边缘 bug。
因为受影响的,恰恰是很多团队在生产里很常见的用法:
- OpenAI 兼容代理网关
- 自托管模型接口
- 企业内部 API Gateway
- 把多家模型统一收口到一个自定义入口的路由层
如果你的部署依赖自定义 Provider 名称,这条报告给出的结论非常糟糕:在受影响版本上,失败频率接近 100%。
结果就是,升级前还正常的自定义模型链路,升级后可能直接变成 完全不可用,而且每一次请求都会在流开始前就死掉。
为什么内置 Provider 可能没事
这条 issue 里一个很关键的细节是:像下面这些内置 Provider:
anthropicopenaigooglegroq
可能仍然可以正常工作。
原因不在于它们“更高级”,而在于它们仍能吃到 pi-ai 内置的环境变量兜底逻辑。
自定义 Provider 名称则没有这层保险。它们更依赖 OpenClaw 把已经解析好的 key 显式传下去。一旦这个回调路径断了,自定义 Provider 就没有第二条路能把 key 带到 stream 层。
报告里指向的回归边界
issue 认为,这件事在使用 @mariozechner/pi-ai <= 0.55.x 的版本里还是好的,而到了 pi-ai 0.63.x 开始坏掉。
被怀疑的上游边界,是 pi-mono 去掉了一个全局 apiKeys map fallback。自那之后,自定义 Provider 如果没有正确挂上 getApiKey 回调,stream 链路就拿不到 key。
这也解释了为什么症状看起来很“反常”:
- 配置里明明有 key
- auth storage 里明明有 key
- model registry 里也还能把 key 解析出来
- 但到了真正 stream 的函数里,
options.apiKey却是undefined
从运维角度看,这种问题最容易误导人,因为你会先怀疑配置写错,实际上坏的是 auth 解析成功之后,到 stream 调用之前的交接层。
怎么确认你撞到的是同一个问题
如果下面几条大部分都成立,就很像是这次回归:
- 你用的是 自定义 Provider 名称,不是内置 Provider id
- 你的 Provider 是 OpenAI 兼容接口,配置在
models.providers下 apiKey明明写在配置里- 只有真正调用模型时才失败
- 错误是
No API key for provider: <custom-name> - 内置 Provider 还能跑,但自定义 Provider 不行
这组信号能把它和一些更常见的错误区分开,例如:
openclaw.json里字段拼错- 环境变量没设
baseUrl写错- 上游凭证本身失效
- 模型 id 不匹配
报告里的诊断信息说明了什么
issue 里给出的诊断日志,基本把问题边界钉在了“key 前面都还在”。
报告称,日志能确认下面几件事:
- provider 归一化时能看到
hasApiKey=true - auth 解析阶段能从
models.json找到自定义 key - runtime auth storage 成功记录了这个 key
- registry 查询仍能返回
{ ok: true, apiKey: <valid> }
但 downstream 的 stream 函数还是会抛出 No API key for provider。
这说明:问题大概率不在 operator 的配置条目本身。
现在应该怎么止血
在上游修复落地前,更稳妥的做法是把 自定义 Provider 链路视为强版本敏感项。
1)先确认是不是升级到了 pi-ai 0.63+ 这条链
如果你的自定义 Provider 是在 OpenClaw 升级后突然坏掉,先检查新版本是不是引入了 issue 指向的 pi-ai 边界。
2)单独测一下内置 Provider
如果 openai/... 或其他内置 Provider 还能工作,而自定义 Provider 一定失败,这几乎就是一个强信号:你命中的不是网络问题,也不是凭证全局失效,而是自定义 key 透传路径回归。
3)不要把“配置里有 key”误判成“stream 链路没问题”
这次 bug 最容易误导人的地方就在这里:
- key 存在于配置
- key 存在于 auth storage
- 但 key 仍然没有真正到达 stream 调用层
所以别因为配置文件看着正确,就过早结束排查。
4)关键业务链路优先考虑回退或 pin 版本
如果自定义 Provider 承担的是收入相关、生产环境或对外服务链路,短期内最稳的策略,很可能不是继续硬扛,而是 pin 到回归前的版本链,或者直接回退到已知可用版本。
issue 提到的临时代码 workaround
该 issue 给了一个代码级 workaround:在 createAgentSession 返回后,手动给 Agent 实例注入 getApiKey 回调,让它能从 auth storage 拿到 provider key。
这对维护者定位问题很有价值,但对大多数运维来说,真正有用的结论更简单:
这更像是一条代码路径回归,而不是文档不清或配置习惯错误。
如果你跑的是打包版或常规部署版 OpenClaw,短期更现实的方案通常是等待上游修复,或者回退版本,而不是自己在运行时补丁里硬改。
维护者真正需要修什么
按 issue 的判断,修复方向其实很明确:
- 确保 Agent / session 链路拿到
getApiKey(provider)回调 - 保证自定义 Provider 在 stream 阶段也能吃到已解析的 key
- 不要让“前面已经 auth 成功”的自定义 Provider,到了真正调用时又像没配 key 一样
从 operator 的合理预期出发,只要 models.providers.<name>.apiKey 已经成功解析,stream 层就不该再把它当作不存在。
结论
如果你的 OpenClaw 部署依赖自定义 OpenAI 兼容 Provider,并且升级后突然开始报 No API key for provider,先别急着把锅甩给配置本身。
按当前这条报告,更像的解释是:key 其实还在,也被前面的链路正确解析了,但运行时没有把它继续传到自定义 Provider 的 stream 函数里。
如果你是从中文首页、安装页或迁移指南跳过来的
GA4 现在把这篇 custom provider API key 问题页放进中文入口的小流量簇里。先把它和安装失败、旧 Moltbot 配置迁移、以及官方 provider key 缺失分开,避免把所有 “No API key” 都归到同一个原因。
- 刚安装 OpenClaw,任何 provider 都跑不通:先回到 Mac 安装指南 或 安装成功检查清单,确认环境变量、Gateway 和 Web UI 都正常。
- 从 Moltbot 迁移后还沿用旧 provider 名、旧配置路径或旧启动命令:先看 1 分钟迁移指南,再回到本页检查 custom provider 映射。
- 只有 Pi AI 0.63 之后的 custom provider 报
No API key for provider:继续留在本页,重点核对 provider id、runtime order、custom key 名称和实际读取到的环境变量。
这个分流的目标是把 “没装好 / 没迁好 / custom provider key 没映射好” 三类高意图问题拆开,让真正的 API key 读不到问题留在本页解决。
FAQ:第一次失败后最该先做的两个判断
怎样快速判断这更像是每个 provider 的 key 解析问题,而不是 provider 或模型整体挂了?
先看故障是不是“只打在自定义 provider 身上”。
如果下面这些现象同时成立,就更像是 key 透传链路回归:
- 自定义 provider 一调用就报
No API key for provider - 同一套部署里,
openai、anthropic这类内置 provider 仍然可用 - 配置检查时,
models.providers.<name>下的apiKey仍然存在 - 故障发生在真正调用模型时,而不是启动校验阶段
这种组合更该优先怀疑每个 provider 的 auth handoff,而不是上游整体宕机或模型端点失活。
改完自定义 provider 的 API key 绑定后最该先核对什么?
别只看到一次请求成功就算修好了。
更稳妥的核对顺序是:
- 之前必挂的自定义 provider,至少能成功完成一次真实流式请求
- 内置 provider 仍然正常,说明这次修复没有顺手伤到标准 provider 路径
agents.defaults.model.primary里使用的 provider 名称,仍然和配置里的自定义 provider id 一致- 当前成功不是被环境变量 fallback 偶然兜住,而是真正修好了自定义 provider 的 key 交接
- 日志里不再出现旧的
No API key for providerstream 启动报错
后两步尤其关键,因为回退或半套补丁很容易让某一条 happy path 看起来恢复了,但自定义 provider 的真正路由契约还没完全一致。
如果你已经确认是自定义 provider key 透传回归,下一步最该补哪层判断
如果你已经基本确认不是 key 没配,而是自定义 provider 在真正 stream 调用时拿不到 key,下一步最值得补的判断通常有两层:
- 先看 Codex OAuth 登录成功但运行时仍回退默认配置,把 provider 认证成功但运行时路由没落好,和“自定义 provider key 没透传到 stream”区分开;
- 再看 OpenClaw Agents 排障指南:任务卡住、工具不回、结果异常时先查什么,确认是不是还叠加了网络、权限、工具或消息链路层面的假象。
这层分流很重要,因为很多人会把“provider 选对了但 key 没到”与“runtime 其实根本没落到目标 provider”混成同一个问题。
值班时先把自定义 provider 故障分成三层
如果读者是从 No API key for provider、custom provider api key not found 或 Pi AI 0.63 升级问题搜进来,先不要直接改密钥。更稳的分流是按这三层判断:
- 配置层:
agents.defaults.model.primary里的 provider id 是否和自定义 provider 完全一致,包括大小写和前缀。这里错了,任何运行时修复都不会生效。 - 传递层:配置里能看到 key,但 stream 启动时仍报
No API key for provider。这更像当前这类 key handoff 回归,应优先保留日志和版本号。 - 回退层:换回内置 provider 或旧版
pi-ai后恢复。这说明业务 prompt、网络和模型本身大概率不是主因,可以把排查范围收窄到 provider adapter。
这三层能把一次搜索访问转成可执行判断:到底是用户配置错误、运行时没有把 key 传下去,还是升级后 adapter 合约变了。
修复、回退或补丁后,先做 4 个收口检查
当你已经改完 key 透传、回退到旧版,或者合上了上游补丁,不要只看一次请求成功就结束。更稳的顺序是:
- 复测失败过的自定义 provider:让它至少完成一次真实流式请求,而不是只看配置文件。
- 复测内置 provider:确认
openai、anthropic这类路径仍正常,避免修复顺手伤到标准链路。 - 核对实际路由名:再次检查
agents.defaults.model.primary和自定义 provider id 是否仍完全一致。 - 回看日志留痕:确认日志里不再出现旧的
No API key for provider启动报错。
这 4 步能把“看起来恢复了”变成“自定义 provider 的 handoff 真的恢复了”。
修改 provider 设置前的预检查清单
在改生产 agent 或轮换密钥前,先按这个顺序确认:
- UI 里的 provider 名称要和运行时实际使用的 provider identifier 完全一致。
- API key 要保存在你正在测试的 agent 作用域里,而不是只存在全局配置或旧 profile。
- 改完 key 后只重启受影响的 agent,再发一次低成本请求确认 key 路径真的生效。
- 如果错误仍然是
No API key for provider,先把 provider id、model id、runtime version 记录到事故备注里,再继续改配置。
这样可以把排查收敛在缺失 key 路径上,避免一次 provider-key 事故被扩大成整套配置重写。
如果你是从 troubleshooting 或 setup 进来,先分清缺 key 症状和 provider 路由错误
GA4 现在把这篇和 setup、troubleshooting、其他运维 bug 页放在同一组线索里。说明它已经不是单纯发布说明,而是很多人看到 No API key for provider 后的恢复入口。
轮换密钥或改 runtime 配置前,先按三类拆开:
- setup 还没真正完成:先确认 provider 已选中、key 写在运行时实际读取的位置,并且改完后已经重启应用。
- key 存在但选错 provider:检查 model 到 provider 的路由、自定义 provider alias,以及是否 fallback 到 Pi AI 或默认 OpenAI 路径。
- 只有升级后的 custom-provider 调用失败:按本文描述的回归处理,保留失败的 model/provider 组合,避免盲目大范围换密钥。
这样能让从高意图排障入口进来的读者,先判断是 provider 选择/透传问题,还是密钥本身真的缺失。
下一步优先覆盖的精确 provider key 搜索词
当操作者不是在排查所有 provider,而是自定义 provider 明明配了 key,运行时仍报 No API key for provider,优先用这一段承接搜索意图。
-
Pi AI custom provider no API key for provider:先确认运行时使用的 provider id 和 key 名完全一致,包括大小写和 alias。
-
OpenClaw custom provider api key 更新后不生效:检查 key 是否还停在旧配置路径,或是否已经迁移到新版 credentials 路径,再决定是否重启。
-
No API key for provider 但 env var 已设置:确认 gateway 进程实际继承了环境变量,而不是只有当前交互 shell 能看到。
-
Pi AI 0.63 no API key for provider after upgrade:先核对当前 provider id 是否仍能命中 runtime 使用的 key lookup 路径。
-
OpenClaw custom provider API key not found:不要急着轮换可用 key,先查 environment variables、provider aliases 和生成后的 runtime config。
-
fix custom provider no api key for provider OpenClaw:用最小 custom provider 调用复现,再对比升级前后的 provider name。
自定义 provider 报 no API key 时,先确认 key 归属层级
No API key for provider 不一定说明密钥不存在。更常见的是 key 写在了全局配置、agent 配置、runtime 环境变量或自定义 provider 名称中的某一层,但实际调用时走了另一层 provider id。排查时先不要反复重填密钥,而是把“provider 名称、key 来源、agent 实际命中路径”对齐。
建议按三步检查:
- 确认报错里的 provider id,是否和配置里保存 API key 的 id 完全一致;
- 检查 agent 级 override 是否覆盖了全局 provider 顺序或 key 读取路径;
- 用一条最小模型请求验证当前 runtime 真正命中了哪个 provider,而不是只看登录或配置页面显示。
这段覆盖 “OpenClaw custom provider no API key”“Pi AI 0.63 custom provider key failed”“自定义 provider API key 不生效” 这类搜索意图,把读者从重复粘贴密钥引到层级归因。
相关阅读
来源
FAQ:回退、修复或补丁后,怎么确认真的从搜索词对应故障里走出来了
先恢复了一次请求成功,为什么还不能急着判定问题已解决
因为这类故障最容易出现“表面恢复、底层没完全通”的假象。
比如你可能只是:
- 临时切回了一个仍带环境变量 fallback 的 provider
- 命中了某条偶然可用的非流式路径
- provider 名称和真正调用的模型别名没有完全对齐
所以更稳的验证标准,不是一条请求成功,而是下面这组连续证据:
- 之前必现失败的自定义 provider,已经能完成至少一次真实流式请求
- 同一环境下内置 provider 仍然正常,说明这次修复没有顺手伤到标准路径
agents.defaults.model.primary里引用的 provider 名称,和models.providers里的自定义 id 仍然完全一致- 日志里不再出现旧的
No API key for provider报错 - 下一次重启或重新建 session 后,问题不会立刻回归
这组检查的意义在于,它能把“只是暂时绕过去了”和“自定义 provider 的 key 透传链路真的恢复了”区分开。
如果线上只剩自定义 provider 失败,最值得先补哪一个排障记录
最值得补的一条内部记录,不是“某模型不能用”,而是一次结构化对照:
- 哪个 OpenClaw 版本开始出问题
- 哪个
pi-ai/pi-mono边界开始出问题 - 哪个自定义 provider 名称失败
- 同环境下哪些内置 provider 仍然正常
- key 在 config、auth storage、runtime log 三处分别是什么状态
这份记录很关键,因为它能直接帮助团队判断:
- 这是版本回归
- 这是 provider 级 handoff 断裂
- 还是你们自己部署里还有别的命名或凭证漂移
从增长视角看,这类 FAQ 之所以重要,是因为搜 No API key for provider custom provider openclaw 进来的用户,往往不是想读原理,而是想快速确认“我是不是命中了同一个回归边界”。
先不要重启所有服务,也不要马上换 key。最快的判断路径是做一个小矩阵:同一个 OpenClaw 版本、同一台机器上,分别跑一个内置 provider 和一个 custom provider。
- 内置 provider 成功,custom provider 失败:优先怀疑 custom provider 的
getApiKey透传路径,而不是网络或模型供应商整体故障。 - 内置和 custom 都失败:先回到环境变量、代理、防火墙、上游账号额度和 Gateway 日志,不要直接套用本文的 pi-ai 0.63 回归结论。
- 只有某一个 custom provider 失败:重点检查 provider id、模型 id、baseUrl、key 名称和实际运行时读取的配置文件是否一致。
恢复前要留下哪些证据?
如果这条链路承载生产任务,恢复前至少留下这 4 个证据,方便回滚后判断是否真的修好:
- 失败请求的 provider id 和 model id。
- 当前 OpenClaw、pi-ai、部署镜像或 lockfile 版本。
- 内置 provider 与 custom provider 的对照测试结果。
- 日志里能证明 key 已解析但 stream 层仍报错的片段。
这样做的价值是避免“换了 key 正好遇到缓存刷新”这种假修复。真正的恢复标准不是错误暂时消失,而是 custom provider 在同一版本链、同一模型路由下能稳定完成多次流式响应。
