Repository navigation
Description
Description
Summary
When calling the Zen Anthropic-messages endpoint (POST https://opencode.ai/zen/v1/messages) with an explicit thinking: { type: "enabled", ... } parameter, three of the newest Claude models fail with a 400 invalid_request_error — Error from provider (Console): Upstream request failed. The exact same request body succeeds for the previous-generation models. Without the thinking parameter all of these models return 200, so the trigger is specifically the extended-thinking parameter path, not the models being unavailable.
Downstream impact: because extended-thinking round-trips fail (or silently degrade to non-thinking), assistant turns come back with no thinking block / signature. In multi-turn tool-use sessions this breaks Anthropic prompt-caching of the conversation history (the cached prefix no longer matches byte-for-byte from the first tool call onward), so the entire history is re-billed at full input price every turn. On a ~120k-token fable tool-loop session this showed up as a constant ~$0.033 cache saving (only tools+system cached, ~3.7k tokens) while 120k of history was re-charged each turn.
Environment
- Endpoint:
https://opencode.ai/zen/v1/messages(Anthropic messages API,x-api-keyauth) anthropic-version: 2023-06-01- Isolated by stepping down through layers to rule out client-side variables: first seen as odd caching/cost behavior in an opencode session → reproduced in a second, unrelated client → then reproduced with raw
curland no client at all (matrix + repro below). Same failure across all three, so it's purely server-side (the Zen→upstream hop), not client-specific.
Minimal reproduction
KEY=<your zen key>
# FAILS (400) — claude-fable-5, claude-sonnet-5, claude-opus-4-8
curl -s -X POST "https://opencode.ai/zen/v1/messages" \
-H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
-d '{"model":"claude-fable-5","max_tokens":2000,"thinking":{"type":"enabled","budget_tokens":1024},"messages":[{"role":"user","content":"hi"}]}'
# -> 400 {"type":"error","error":{"type":"invalid_request_error","message":"Error from provider (Console): Upstream request failed"}}
# WORKS (200) — same body, claude-haiku-4-5 / claude-opus-4-6
curl -s -X POST "https://opencode.ai/zen/v1/messages" \
-H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5","max_tokens":2000,"thinking":{"type":"enabled","budget_tokens":1024},"messages":[{"role":"user","content":"hi"}]}'
# -> 200, content = [thinking(signature len ~424), text]Test matrix (identical request body, only model changes)
| Model | thinking enabled |
no thinking param |
|---|---|---|
claude-fable-5 |
400 Upstream request failed | 200 ([thinking, text], adaptive) |
claude-sonnet-5 |
400 Upstream request failed | 200 ([text]) |
claude-opus-4-8 |
400 Upstream request failed | 200 ([text]) |
claude-opus-4-6 |
200 ([thinking, text], signature len 368) |
200 |
claude-haiku-4-5 |
200 ([thinking, text], signature len 424) |
200 |
The failure is cleanly correlated with the newest model generation. Note claude-fable-5 even emits a thinking block on its own when no thinking param is sent, so the model clearly supports thinking — it's the explicit thinking parameter path on the Zen→upstream hop that is broken for these three models.
Expected
thinking-enabled requests for claude-fable-5 / claude-sonnet-5 / claude-opus-4-8 should return 200 with a thinking block (including a valid signature), same as opus-4-6 / haiku-4-5.
Actual
400 invalid_request_error — Error from provider (Console): Upstream request failed. The upstream error detail is not surfaced, which also makes this hard to diagnose from the client side.
Notes / asks
- Could you surface the real upstream error body instead of the generic "Upstream request failed"? It would make issues like this self-diagnosable.
- This looks like a server-side issue in the (closed) Zen API itself, not in the open-source opencode client — it reproduces with raw
curlagainstopencode.ai/zen, independent of any client. I'm filing it here since this is the escalation path to whoever operates Zen; I can only report it, not patch it. Likely a per-model config/routing issue for the newest Claude generation on the Zen→upstream hop (e.g. athinking/budget_tokens/ beta-header mismatch). - Full disclosure on the cost side: before I tracked this down, I'd already spent roughly $60 on fable-5 tool-loop sessions that were silently re-billing the full conversation history every turn because of this caching breakage. I'm not claiming anything owed — but if the team felt like extending some credit toward the time spent isolating and reporting this, I'd genuinely appreciate it. Happy to provide more repro cases, request/response captures, or usage/request IDs to help you trace it upstream.
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity
github-actions commentedon Sep 2, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.