Repository navigation
[Bug] v1.3.202:仅 user:inference 权限的 Setup Token 槽位出站带 cache_control.scope,上游 400(v1.3.194 正常) #637
Description
提交前自查
- 已升级到最新 Release v1.3.202,问题出现;回退 v1.3.194 后消失(升级回归)。
- 已搜索现有 Issues(
scope/Extra inputs are not permitted)。相关的 [Bug] v1.3.190 / CLI 2.1.296:official_full 自动注入 scope=global 导致上游 400 #536 已关闭(重新授权后恢复),本问题现象不同:只在升级后出现、回退即消失,且只影响一种凭证类型,见下。 - 已阅读 ISSUE_GUIDE.md,以下内容已脱敏(无密钥、凭证、IP、域名、邮箱)。
问题类型
请求失败(4xx):升级到 v1.3.202 后,只含 user:inference 权限的官方 Setup Token 槽位上,请求被上游以 cache_control.ephemeral.scope 拒绝;同时运行的另一个槽位(setup-token 类型,即转换后的 Setup Token,持有带 user:profile 的完整权限授权)正常。
1. 版本
- 升级前:v1.3.194(正常,该槽位此前 12 小时内数百次请求无此错误)
- 升级后:v1.3.202(出现)→ 约 6 分钟后回退 v1.3.194(消失)
- 部署:Docker Compose。说明:我们的镜像是
FROM ghcr.io/dofastted/vm2api:v1.3.202加了少量本地补丁(面板租户权限、拦截规则、用量日志视图)。补丁都不涉及cache_control、beta 计算或协议出站,两个版本上补丁内容相同。 - 升级时按升级说明执行了
wrap-cli/sync,两个集群槽位都用/vms/:id/reload换成了新内核镜像(1.3.200 起的 kernel/cli 快照)。回退时同样 sync + reload 换回旧内核。
2. 可复现路线
前置:2 个 Claude 集群槽位(Docker 容器,分别在两个扩展节点上),persona_preset = official_full,persona_templates 为空(没有自定义模板,routing.json 里没有任何 scope 字段)。
| 槽位 | 账号类型(accounts.type) | 凭证 scopes | refresh token | v1.3.202 结果 |
|---|---|---|---|---|
| 槽 A | official-setup-token |
["user:inference"] |
无 | 400 |
| 槽 B | setup-token |
user:inference, user:profile, user:sessions:claude_code, user:mcp_servers, user:file_upload |
有 | 正常 200 |
最小复现(不需要外部客户端):v1.3.202 上对槽 A 调面板测试接口:
curl -s -X POST http://127.0.0.1:8787/api/panel/vms/<槽A>/test-chat \
-H "Authorization: Bearer $VM2API_API_KEY" -H 'content-type: application/json' \
-d '{"model":"claude-haiku-5-5","prompt":"Reply OK."}'- v1.3.202 槽 A:
400 system.3.cache_control.ephemeral.scope: Extra inputs are not permitted(连续 2 次) - v1.3.202 槽 B:
200 OK. - 回退 v1.3.194 + 旧内核后槽 A:haiku、opus 均
200 OK.
外部客户端同样复现:claude-cli/2.1.299 (external, claude-desktop-3p, agent-sdk/...),claude-opus-5-5,stream=true,via=rust-kernel-stream。同一个客户端同一把 key 在 v1.3.194 上 93 次 200、0 次 400;升级后在槽 A 上 4 次 400。
期望 / 实际
- 期望:与 v1.3.194 一样,Setup Token(仅 inference 权限)槽位出站时剥掉上游不接受的
cache_control.scope(anthropic-policy注释里写的“没有 prompt-caching-scope 的 hop 必须去掉 scope”)。 - 实际:
status=400 error_code=upstream_invalid_request final_state=rejected attempt_count=1
message=system.3.cache_control.ephemeral.scope: Extra inputs are not permitted
复现频率
v1.3.202 + 槽 A:必现(6/6,含 2 次面板 test-chat)。槽 B:0 次。v1.3.194:0 次。
3. 运行环境
- 控制面:Ubuntu 24.04.1,内核 6.8,4C/4G,Docker 29.9.0,无
/dev/kvm - 槽位:2 个扩展节点,Docker 容器槽,Claude 平台
- 代理:每个槽位各自绑定 SOCKS5 出口
源码定位(推测,未证实)
cache-ttl.mjs 与 anthropic-policy.mjs 中 scope 剥离相关代码在 v1.3.194 和 v1.3.202 之间看起来没有变化,所以怀疑是:
- v1.3.200 的 kernel/cli-node 快照(
payload-2026.10.19-kernel-cli)在 Setup Token 路径上自己带上了scope;或 - v1.3.201 的消息线程 beta 记忆(fix: pin thread betas and verify live docker memory #621)/ v1.3.202 的凭证合并改动让该凭证类型的 hop 被判定为带
prompt-caching-scope,于是没有剥离 scope,但上游对 inference-only token 不认。
只影响 inference-only 的 official-setup-token,而带完整 scopes 的 setup-token 正常,这一点可能是关键线索。
补充
- 当时日志是 normal 模式,没有抓到 Debug 出站体;本机内部 request id:
050d1af1-4c3d-464c-a3ed-b1feb0509c37、9e1e86d9-a65c-423c-b5bf-e1390fcd3580(test-chat)。 - 回退过程中另有 1 次
503 read ECONNRESET,时间点正好是槽 A reload 换容器,判断为升级重启造成,和本问题无关。 - 需要的话我们可以在低峰期临时升回 v1.3.202,带
X-Kin-Debug: 1抓一次槽 A 的出站 system / anthropic-beta 给你。
Activity