Skip to content

[Bug] AI Gateway: POST /v1/messages returns 400 invalid_request_error when any query string is present, breaking Claude Code integration #13723

Description

@20has

Contact Information

No response

1Panel Version

1.0.1(AI Gateway 为 Docker 部署,镜像 1panel/ai-gateway,2026-09 初拉取)

Problem Description

1Panel AI Gateway 的 Anthropic Messages 接口(POST /v1/messages)只要 URL 携带任意 query 参数(与参数名、参数值均无关),就直接返回 400 invalid_request_error;不带 query 时完全正常。

这导致 Claude Code 无法接入:Claude Code 的 Anthropic 客户端在启用 beta 特性时会固定在 URL 后追加 ?beta=true,客户端侧无法关闭,因此它的所有请求都命中这个 400,界面报 "There's an issue with the selected model",实际与模型无关。

同时确认与「协议转换」开关无关,开关开/关均可复现。

Steps to Reproduce

以下 curl 可从零复现,sk-xxx 替换为网关上任意有效 API Key,<host> 为网关地址:

1. 不带 query —— 正常 200:

curl -s http://<host>/v1/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-xxx" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"auto","max_tokens":32,"messages":[{"role":"user","content":"hi"}]}'

2. 带 ?beta=true —— 400:

curl -s "http://<host>/v1/messages?beta=true" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-xxx" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"auto","max_tokens":32,"messages":[{"role":"user","content":"hi"}]}'

3. 带任意无关参数(排除 beta 语义问题):

curl "http://<host>/v1/messages?x=1"     # 400
curl "http://<host>/v1/messages?beta="   # 400(空值也算)

完整测试矩阵:

请求 结果
POST /v1/messages 200
POST /v1/messages?beta=true 400 invalid_request_error
POST /v1/messages?beta=false 400
POST /v1/messages?beta=(空值) 400
POST /v1/messages?x=1 400
GET /v1/models 200
GET /v1/models?beta=true 200(models 路由不受影响)
GET /v1/models?x=1 200
POST /v1/messages/(尾斜杠) 307
POST /v1/MESSAGES?beta=true(大写) 404

The expected correct result

/v1/messages 路由应按标准 HTTP 语义只匹配路径部分,query 字符串不应影响路由与请求校验(参照 GET /v1/models?beta=true 的正常行为)。Claude Code(会追加 ?beta=true)应可正常接入。

Related log output

POST /v1/messages?beta=true
HTTP/1.1 400 Bad Request
{"type":"error","error":{"type":"invalid_request_error","message":"invalid request"},"request_id":"..."}

Additional Information

排查补充:把 Claude Code 实际发出的完整请求体(约 100KB,含 43 个 tools 以及 cache_control、thinking、context_management、mcp 等全部扩展字段)原样重放到不带 query/v1/messages,上游返回 200。说明请求体解析与字段兼容没有问题,400 完全由 query 字符串触发。

根因推断POST /v1/messages 疑似注册为基于完整原始 URI(含 query)的精确匹配,或在 handler/中间件中显式校验了 RawQuery != "" 后直接返回 400;而 GET /v1/models 走标准 path-only 路由,故不受影响。大小写敏感(大写 404)与尾斜杠 307 也支持"精确匹配"这一判断。

修复建议:Anthropic Messages 路由改为 path-only 匹配、忽略 query(或至少显式容忍 beta 参数)。可参考同类网关 new-api 的行为,其 /v1/messages?beta=true 可正常透传。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions