五分钟搞懂 OpenCode 提示 Not Found 错误:原因 + 解法全在这
五分钟搞懂 OpenCode 的 Not Found 错误:原因 + 解法全在这
上周一个关注我的读者私信说,他用 OpenCode 接自己公司的私有 API 中转,跑了两天都好好的,第三天突然就报 AI_APICallError: Not Found,百思不得其解。
他翻了官方文档,没找到直接的解释。又去 GitHub Issues 搜了一圈,发现同款问题的帖子超过 30 个,但答案散落四处,有人说改配置,有人说清缓存,有人说换模型,搞得他更迷糊了。
我觉得这个错误值得好好说一说,因为我自己也踩过,而且踩的姿势和他完全不同。Not Found 这仨字看起来简单,背后其实有好几种完全不同的根因,乱试一通只会浪费时间。
今天就把我整理的排查思路写出来,对号入座,五分钟解决。
先说结论:Not Found 来自三个方向
在正式展开之前,我想先给你一个整体框架,不然看到后面容易乱。
OpenCode 报 Not Found,本质上是它向 AI 服务商发出的请求,被对方服务器回了一个 404。原因归纳起来就三类:
- 接口路径配错了:你填的 baseURL 不对,请求打到了不存在的路由上
- 模型 ID 写错了:格式不符合规范,服务商找不到对应模型
- 本地缓存过期:provider 包版本太老,跟不上 API 变更
90% 的情况都在这三类里。下面逐一拆解。
原因一:baseURL 路径写错了(最高频)
这是我见过最多人踩的坑,也是最难发现的一个。
很多人用 OpenCode 接私有部署的 API 中转,或者接 OpenRouter、Aiberm 之类的代理服务,需要在配置里填一个自定义的 baseURL。问题就出在这里——你填的 URL 末尾有没有斜杠、路径层级对不对,差一点都会报 Not Found。
先看一个配置案例:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"opencode": {
"models": {
"DeepSeek V4 Flash Free": {
"name": "DeepSeek V4 Flash Free"
},
"npm": "@ai-sdk/openai-compatible",
"options": {
"apiKey": "your-apikey",
"baseURL": "https://opencode.ai/zen",
"setCacheKey": true
}
}
}
}
我曾经就因为这个问题卡了将近半小时。我当时填的是:
"baseURL": "https://opencode.ai/zen"
今天报错: 注意看 "npm": "@ai-sdk/openai-compatible",这代表客户端在使用 OpenAI 兼容模式 去请求接口。
这种模式下,客户端会自动在你的 baseURL 后面加上 /v1/chat/completions。
关键冲突: 配置中地址写的是 "https://opencode.ai/zen"。客户端自动拼接后,最终请求的完整地址变成了: https://opencode.ai/zen/v1/chat/completions 但是根据 OpenCode 的官方标准规范,或者是你使用的这个通道,正确的请求路径可能根本没有 /zen,或者 /zen 应该放在最后,导致服务器找不到这个被拼接出来的扭曲路径,直接给你甩了一个 Not Found(404)。
正确的填法是只填到 /v1 这一级,让 OpenCode 自己去拼后面的路径:
"baseURL": "https://opencode.ai/zen/v1" GitHub Issues 里有个具体的报错日志,错误信息是 Not Found: Route /api/messages not found,一看就是这种情况。
排查方法:打开日志文件(路径在 ~/.local/share/opencode/logs/ 下,文件名带时间戳),找到 url= 那一行,把完整的请求地址复制出来,用 curl 直接请求一下,看返回什么。
原因二:模型 ID 格式写错了
OpenCode 对模型 ID 的格式有严格要求:必须是 provider/model 的形式,缺一不可。
我觉得这里有个特别容易忽略的细节——不同 provider 的 model ID 不一样,你不能把 OpenAI 的写法直接用在 Anthropic 上,也不能把 OpenRouter 的写法用在原生 provider 上。
比如用 OpenRouter 的时候,正确写法是:
openrouter/anthropic/claude-sonnet-4-5
有人会习惯性地写成 claude-sonnet-4-5,或者 anthropic/claude-sonnet-4-5,少了 openrouter/ 这个前缀,系统就找不到对应的模型配置,然后报 Not Found。
另外提醒一下,模型 ID 要去对应服务商的官方文档里查最新的,不要凭记忆写。OpenAI 和 Anthropic 隔几个月就会更新模型名称,写错了同样是 404。
快速验证方法:在 OpenCode 里输入 /models,会列出当前可用的所有模型,直接从列表里选,不用手动填。
原因三:provider 包过期,缓存没更新
这个原因比较隐蔽,因为你什么都没改,突然就报错了。
OpenCode 有一个机制:它会根据需要动态下载各家 provider 的 SDK 包,并缓存到本地。好处是按需加载、省空间;坏处是如果 AI 服务商悄悄更新了 API 格式或者参数,你本地的缓存包还是旧版本,就会出现兼容性问题,报错方式之一就是 Not Found。
这种情况的特征是:用了一段时间好好的,某天突然开始报错,配置没有任何改动。
解决方法很直接,清掉 provider 缓存,让 OpenCode 重新下载:
# 删除缓存目录
rm -rf ~/.local/share/opencode/providers
# 重启 OpenCode,它会自动重新下载
opencode
Windows 用户对应的缓存目录在 %AppData%\opencode\providers。
我建议每次 OpenCode 大版本更新后都做一次这个操作,预防性清理,省得关键时刻抓瞎。
附加情况:用 OpenRouter 时报 "User not found"
这是 Not Found 错误的一个变体,专门坑 OpenRouter 用户,值得单独说一下。
症状是:API Key 明明有效(直接 curl 调 OpenRouter 的接口完全没问题),但 OpenCode 就是报 AI_APICallError: User not found。
这个问题的根源不在 Key,而在于 OpenCode 读取 Key 的方式。有时候用环境变量 OPENROUTER_API_KEY 设置的 Key,没有被 OpenCode 正确识别,因为它优先读 ~/.local/share/opencode/auth.json 里的配置。
解决方法:不要只靠环境变量,用 OpenCode 内置的 /connect 命令来配置,它会把 Key 写入 auth.json:
# 在 OpenCode 里输入
/connect
# 按提示选择 OpenRouter,粘贴 API Key
配置完之后退出重启,问题基本就解决了。
三步排查总结
把上面的内容收拢一下,遇到 Not Found 的时候,我建议按这个顺序来:
第一步,看日志
找到 url= 那行,把完整请求地址复制出来,用 curl 手动请求,判断是路径问题还是认证问题。日志开启 DEBUG 模式会更详细:opencode --log-level DEBUG。
第二步,查配置
检查 opencode.json 里的 baseURL 是否只填到 /v1 这一级,检查模型 ID 是否符合 provider/model 格式,用 /models 命令验证模型是否在可用列表里。
第三步,清缓存
如果前两步都没问题,删掉 ~/.local/share/opencode/providers 目录,重启 OpenCode,让它重新拉取最新的 provider 包。
三步走完,95% 的 Not Found 都能解决。剩下解决不了的,去官方 GitHub Issues 搜一下具体的报错信息,基本都有人踩过了。
最后说一句
我觉得 OpenCode 这个工具整体很好用,尤其是支持多 provider 切换这点,对不想被单一平台绑死的开发者来说很友好。但配置这块确实不够傻瓜,文档也有点散,很多报错信息不够直白,新手容易踩坑。
我自己从第一次报 Not Found 到摸清楚规律,大概花了两三个小时。写这篇文章就是想帮后来的人把这个时间压缩到五分钟。
你用 OpenCode 踩过哪种 Not Found?或者遇到过什么其他奇怪的报错? 评论区聊聊,说不定我下篇正好写你踩的那个坑。
觉得有用的话转发再看,让更多用 OpenCode 的朋友看到这篇——毕竟谁也不想在报错上浪费半天。
