Claude Code 报 model_not_found?在 settings.json 里映射模型排查

Claude Code 接入自定义端点后出现 model_not_found,很多人第一反应是重新生成 Key,或者把模型名改成聊天界面里看到的显示名。这个顺序往往不对:ANTHROPIC_BASE_URL 解决的是请求去哪里,模型变量解决的是请求里带什么 ID;两者都正确,服务端仍可能因为模型未开放、别名不接受或配置作用域没有生效而返回 404。

这篇文章只解决一个问题:Claude Code 已经写了 settings.json,请求却提示模型不存在,怎样按配置作用域、Base URL、模型变量和真实请求结果逐层定位。本文使用本机 Claude Code 2.1.191 和一个只监听 127.0.0.1 的 Anthropic Messages 夹具,错误模型返回 404,正确模型返回 200。没有使用真实 Key,也没有请求线上 Anthropic 或网关。

先按这 4 步跑通

适用环境:已经安装 Claude Code,并准备通过环境变量把请求发到自定义 Anthropic 兼容端点。本文先以 macOS/Linux 为例;Windows 用户可以把用户级目录换成 %USERPROFILE%\\.claude\\settings.json,项目级文件仍放在项目目录的 .claude/settings.json

1. 先确认 settings.json 的作用域

官方文档把用户设置放在 ~/.claude/settings.json,项目共享设置放在项目目录的 .claude/settings.json。两个文件的用途不同:用户设置影响你打开的多个项目,项目设置适合随仓库共享的非敏感配置。先看你改的是哪一层:

ls -l ~/.claude/settings.json
ls -l .claude/settings.json 2>/dev/null || true

如果两个文件都存在,不要假设后改的文件一定覆盖全部字段。先把模型和 Base URL 放到一次测试明确使用的作用域里,再逐步恢复项目级配置。真实 Key 不要提交到仓库;本文用的是本地夹具哨兵。

2. 写入最小 settings.json

先用一份只包含环境变量的最小文件验证链路:

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://127.0.0.1:PORT",
    "ANTHROPIC_API_KEY": "fixture-only",
    "ANTHROPIC_MODEL": "fixture-sonnet",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "fixture-sonnet"
  }
}

PORT 是本地夹具启动后打印的端口,线上配置时应换成目标服务文档规定的地址。ANTHROPIC_BASE_URL 决定请求发送到哪里;ANTHROPIC_MODEL 是当前会话要使用的模型值;ANTHROPIC_DEFAULT_SONNET_MODEL 这类变量用于把 Claude Code 的家族别名映射到 provider 真正接受的模型 ID。不要把 fixture-sonnet、聊天页面显示名或另一家服务的模型别名直接当作所有网关都接受的值。

3. 用当前 CLI 读这份设置

本文的本机版本是 Claude Code 2.1.191。使用 --bare 和显式 --settings,减少用户目录里其他插件、记忆和密钥链的干扰:

claude --bare \\
  --settings /path/to/settings.json \\
  --tools "" \\
  --print "hello"

成功信号不是“命令启动了”,而是本地服务返回 200,并且 CLI 输出 fixture success。如果模型不存在,Claude Code 可能把服务端的 404 归纳为 There's an issue with the selected model (...),这仍然是模型选择错误分支;要同时保留 HTTP 状态和 CLI 提示,才能知道失败发生在哪一层。

4. 先用模型 ID 做最小验证

如果你的服务提供模型列表,先读取它给出的真实 ID,再填入 ANTHROPIC_MODEL。如果没有模型列表接口,就从服务文档或控制台复制当前确实开放的 ID,并用一条最小消息请求验证。不要先加复杂 prompt、工具调用或长上下文,因为那会把模型不存在、权限不足和请求体不兼容混在一起。

本地实测:404 和 200 的分界

为了不把示例配置写成线上结论,我启动了一个本地 Anthropic Messages 夹具。它只接收 POST /v1/messagesunknown-model 返回 JSON 错误和 HTTP 404,fixture-sonnet 返回最小消息响应和 HTTP 200。Claude Code 实际请求路径带有 ?beta=true,夹具也记录了这个真实路径,说明请求确实从 CLI 走到了配置的 Base URL。

执行:

python3 06-evidence/probe_claude_settings.py

本次输出的关键结果:

CLAUDE_VERSION=2.1.191 (Claude Code)
UNKNOWN_MODEL_EXIT=1
UNKNOWN_MODEL_SIGNAL=selected-model-error
UNKNOWN_MODEL_HTTP=404
SUCCESS_MODEL_EXIT=0
SUCCESS_MODEL_SIGNAL=fixture success
SUCCESS_MODEL_HTTP=200
REQUESTS=[{"model": "unknown-model", "path": "/v1/messages?beta=true", "status": 404}, {"model": "fixture-sonnet", "path": "/v1/messages?beta=true", "status": 200}]
ONLINE_PROVIDER_REQUEST=NO

这组结果说明三件事。第一,错误模型确实进入了消息请求,服务端用 404 拒绝它,CLI 将其显示为“所选模型存在问题”;第二,换成夹具声明的真实模型 ID 后,CLI 退出码为 0,并输出 fixture success;第三,Base URL 的请求去向可以通过夹具记录的 path 验证,但这不等于某个真实网关支持该模型。

实测结果图:

Claude Code 模型映射 404 与 200 实测结果

model_not_found 应该按什么顺序排

情况一:改错了 settings scope

用户设置和项目设置都存在时,先退出当前 Claude Code 会话,再用一个明确的 --settings 文件做最小验证。确认最小文件能跑通后,再把需要共享的非敏感字段迁回项目设置。不要把 API Key 写进 .claude/settings.json 并提交到仓库;项目设置适合权限和工具边界,不适合明文凭据。

情况二:Base URL 指向了错误协议

ANTHROPIC_BASE_URL 应指向目标服务规定的 Anthropic API 基地址,不是官网登录页,也不是 OpenAI Chat Completions 的资源路径。官方文档明确说它改变请求去向,但不会改变模型选择。若把 OpenAI 兼容端点直接填给只接受 Anthropic Messages 的客户端,错误可能表现为 404、405、协议解析失败或统一网关错误;不要只看“域名能打开”就认为协议匹配。

情况三:模型显示名和 provider ID 不一致

“Sonnet”“Claude Sonnet”“某平台的 Claude-Sonnet-日期后缀”可能只是 UI 名称或别名。自定义 provider 通常要求它自己的模型 ID。先用模型列表或文档确定实际值,再填 ANTHROPIC_MODEL;如果使用默认别名映射,就同时记录别名和最终 provider ID,方便排查。

情况四:Key 有效,但模型权限不足

模型不存在、模型未开放和凭据没有该模型权限,不一定由同一个 HTTP 状态表达。文章的夹具用 404 表示“模型 ID 不存在”,但真实服务也可能返回 401、403 或自定义错误 JSON。此时不要继续轮换 Key,先看错误类型、request id、目标模型和请求去向;只有确认认证失败,才进入 Key 分支。

失败路径与最小记录

  1. **settings 文件不存在。** 先记录当前工作目录、用户目录和 CLI 版本,修正作用域。
  2. **配置能加载,但请求没有到目标地址。** 检查 ANTHROPIC_BASE_URL 是否为空、是否被项目设置覆盖,以及是否需要重启会话。
  3. **请求到达后 HTTP 404。** 记录模型 ID、状态码、request id 和错误类别;不要记录完整 Key 或请求体。
  4. **请求返回 401/403。** 核对认证方式、Key 作用域和服务权限,不要把它和模型不存在混为一谈。
  5. **模型 200,但 CLI 仍失败。** 再检查 Anthropic Messages 响应结构、流式事件、工具调用和版本兼容,不要直接把失败归因于模型名。

安全边界

示例中的 fixture-onlyunknown-modelfixture-sonnet 都是本地测试值。真实 API Key 不应出现在仓库、截图、Issue、日志或 shell history 中。排错截图只保留状态码、模型 ID 和脱敏的请求路径;如果模型 ID 本身属于内部项目,也应先按组织规则脱敏。

本文是纯排错教程,不要求注册、购买、充值或使用某个商业服务。它只证明当前 CLI 可以把两个合成模型分支发送到一个合成端点;真实服务的模型名、认证方式、协议支持和错误码,仍必须以当日官方文档和实际响应为准。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐