Provider API: region-restricted Claude 5.5 models return 403 "Authentication failed", which makes Claude Code prompt `/login` (and `thinking.type.enabled` 400 is double-encoded)
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
The report points to the error mapping for POST /provider/v1/messages but names no source files or tests. Start by locating that endpoint and tracing how upstream region refusals and invalid_request_error responses are converted. Done means region refusals have a distinct code while plan and credential errors retain their meanings, and the thinking.type=enabled error has a flat message.
由索引模型根據 Issue 內容生成。
描述
Provider API: region-restricted Claude 5.5 models return 403 "Authentication failed", which makes Claude Code prompt /login; the same endpoint also 400s on thinking.type=enabled with a double-encoded message
No API keys, account ids, prompts, or org names are included below.
Summary
Two separate defects, both hit through POST https://api.commandcode.ai/provider/v1/messages with a GOAT plan:
-
Region-restricted models surface as a credential error. For
claude-sonnet-5-5/claude-haiku-5-5, when the request is refused for region/edge reasons the API answers with the credential-shaped body403 permission_error "Authentication failed. Please check your credentials.". Because clients key onpermission_error/authentication_failed, Claude Code turns this intoPlease run /login · API Error: 403 ...— a login prompt for a key that is fine and never stopped working for other models. -
thinking.type.enabledis rejected with a nested, double-encoded error. Clients that still send the pre-5.5 thinking shape get400whosemessageis a stringified JSON document rather than a message, so it can't be pattern-matched or shown usefully.
This is the same class as #930 (region restriction mapped onto an auth error) and the same models as the Korea report in #945 (HKG edge 403 ×16 / NRT edge 200 ×5, same key, seconds apart). Filing separately because the client-visible harm here is the /login prompt, and because of the second defect.
Actual Behavior
1) Region-restricted refusal, credential-shaped
HTTP/2 403
{"type":"error","error":{"type":"permission_error","message":"Authentication failed. Please check your credentials."}}
What the client does with it (Claude Code 2.1.300, same key, same session):
Please run /login · API Error: 403 Command Code: Authentication failed. Please check your credentials.
...with the persisted record marked "error": "authentication_failed", "apiErrorStatus": 403. The user is told to re-authenticate a credential that is valid; re-login does not help, and the next model choice works.
2) thinking.type.enabled
POST /provider/v1/messages
{"model":"claude-sonnet-5-5","max_tokens":4096,
"thinking":{"type":"enabled","budget_tokens":2048},
"messages":[{"role":"user","content":"hi"}]}
HTTP/2 400
{"type":"error","error":{"type":"invalid_request_error","message":
"{\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":
\"\\\"thinking.type.enabled\\\" is not supported for this model. Use \\\"thinking.type.adaptive\\\" and \\\"output_config.effort\\\" to control thinking behavior.\"},
\"request_id\":\"req_...\"}"}}
The text is correct but it arrives as an escaped JSON string inside message, so it is not message-shaped and not matchable. thinking.type=adaptive + output_config.effort returns 200.
Expected Behavior
- A region/edge refusal should not reuse
authentication_failed. A distinct code is enough, e.g.
403 {"error":{"message":"claude-sonnet-5-5 is not available in your region.","type":"permission_error","code":"MODEL_NOT_AVAILABLE_IN_REGION"}}
—MODEL_NOT_IN_PLANfor plan gates is already correct and should not regress;401 authentication_errorshould stay reserved for real credential problems. - The
thinking.type.enabledrejection should return the inner message as a flatmessagestring (not stringified JSON).
Evidence
Region-shaped refusal — our account, 2026-10-16, all times CST (UTC+8)
Same key throughout; no config change; deepseek/deepseek-v4.1-flash on the same key and same endpoint was 31/31 × 200 in the same window, which is the control proving the key and the endpoint were healthy.
| Window | Attempts on 5.5 models | 200 | 403 | 400 |
|---|---|---|---|---|
| 11:00:30 → 12:04:58 | 34 | 0 | 32 | 2 |
- Last success before the window: 10:04:47
- First success after the window: 19:11:12 (≈ 9h later, nothing changed on our side)
- Clients hit:
claude(Claude Code),curl,Python-urllib,pi— 4 different shapes, all 403, so it is not a header or body problem. - 403 latencies were 21–675 ms, i.e. rejected upstream, not our request being wrong.
- 3 of them came back as
403 Command Code: CAPTUREDin 21–29 ms (edge/WAF shape).
This also corrects one point in the support reply for our account: there were no claude-sonnet-5-5 successes interleaved with the refusals between 11:04 and 11:07 on this key — the run was a clean 34-attempt, zero-success window.
Region is the variable, not the account (reproducible shape)
Same key, same second, only the egress changes:
| Egress | Cloudflare loc |
Result |
|---|---|---|
| JP tunnel node | JP / colo=KIX |
200 ×N |
| CN residential (Shanghai) | CN / colo=LAX |
200 ×N |
And in #945 a Korea user showed the same split on these exact two models: every cf-ray ending -HKG failed, every -NRT succeeded. So the refusal follows the edge the request lands on, which is consistent with the support reply — the problem is only that the wire format says "your credentials are bad".
Steps to reproduce
- On a GOAT plan,
POST /provider/v1/messageswithmodel=claude-sonnet-5-5,max_tokens: 16, one user message — from an egress whose Cloudflare colo is a refused one (e.g.HKG):
→403 {"type":"error","error":{"type":"permission_error","message":"Authentication failed. Please check your credentials."}} - Same key,
model=claude-sonnet-5→403 MODEL_NOT_IN_PLAN(auth passed; plan gate reported correctly). - Same key,
model=deepseek/deepseek-v4.1-flashvia/provider/v1/chat/completions→200. - Point Claude Code at the Provider API and send one message while the egress hits the refused colo → the client shows
Please run /login, persistsauthentication_failed. - Send
thinking: {"type":"enabled","budget_tokens":2048}toclaude-sonnet-5-5→ the double-encoded400above.
Command Code Version
Not applicable — reproduced against the Provider API directly (curl), no cmd installed on the machine. Claude Code 2.1.300 was the affected client for defect 1.
Operating System
macOS
Terminal/IDE
zsh + curl 8.x; Claude Code 2.1.300
Shell
zsh
Session file (optional)
Not attached — it contains the whole session. The two lines that matter are quoted verbatim above.
Fix prompt (optional)
Two things to fix, both in the Provider API error path.
-
Region refusals must not be
authentication_failed.
Location: whatever maps the upstream Anthropic refusal into/provider/v1/messagesresponses — today it collapses to403 permission_error "Authentication failed. Please check your credentials.".
Correct: return a distinctcode(e.g.MODEL_NOT_AVAILABLE_IN_REGION) and a message naming the model. KeepMODEL_NOT_IN_PLANfor plan gates and401 authentication_errorfor real credential failures. Evidence that the reason is known internally: the CLI already prints the region reason for other models (see #930), and the API itself reports plan gates correctly on the same key. -
Stop double-encoding upstream
invalid_request_errors.
Location: the same mapping layer. When the upstream body is{"type":"error","error":{"type":"invalid_request_error","message":"..."}}, the innermessageis being stringified into the outermessage. Flatten it somessageis the plain sentence.
How to check: from an egress that lands on a refused colo, curl the three model cases in the Evidence table — expect MODEL_NOT_AVAILABLE_IN_REGION, MODEL_NOT_IN_PLAN, 200 respectively; and thinking.type.enabled should return a flat invalid_request_error message.
- 主要語言
- 沒有語言資料
- 星號
- 4.2k
- 分支
- 377
- 平均合併
- 1 天 17 分鐘
- 30 天內合併 PR
- 7
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
CommandCodeAI/command-code 的其他 Issue
-
Provider /v1/messages rejects role:"system" inside messages[] — Claude Code ≥ 2.1.154 incompatible未關閉
難度 2/5 1-3 小時 新手友好度 75/100
CommandCodeAI/command-code#1085 ·
維護者通常 1 天內回覆
-
Feature request: auto-reconnect remote control (/rc) after restart可能已有人在做 @aliarain 於 20 天前認領。 未關閉p2
難度 2/5 1-3 小時 新手友好度 85/100
CommandCodeAI/command-code#992 · 1 則留言 · 已指派 1 人 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 68/100
CommandCodeAI/command-code#933 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 68/100
CommandCodeAI/command-code#855 ·
維護者通常 1 天內回覆
-
grep tool passes empty file type to ripgrep可能已有人在做 @ahmadbilaldev 於 19 天前認領。 未關閉
難度 2/5 1-3 小時 新手友好度 68/100
CommandCodeAI/command-code#655 · 1 則留言 ·
維護者通常 1 天內回覆
查看 CommandCodeAI/command-code 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 85/100
-
難度 2/5 1-3 小時 新手友好度 78/100
UKGovernmentBEIS/inspect_ai#6512 ·
維護者通常 1 天內回覆
-
area/c++ area/core kind/bug-report
難度 2/5 1-3 小時 新手友好度 78/100
tensorflow/quantum#1140 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
-
難度 1/5 1 小時以內 新手友好度 68/100
Kav-K/GPTDiscord#501 ·
維護者通常 1 天內回覆