Repository navigation
Description
Description
Requests to OpenCode Go models qwen3.8-flash / qwen3.8-max on https://opencode.ai/inference/go/anthropic/v1/messages that are rejected by the upstream backend (e.g. thinking.budget_tokens >= max_tokens) return HTTP 400 with the SSE body event: error\ndata: {} — the real upstream error message is dropped. opencode then shows the useless "Provider request failed with HTTP 400: event: error data: {}" after its retries.
The same class of validation error is NOT masked on other Go paths: claude-haiku-5-5 returns a readable invalid_request_error message, and a request without x-opencode-session returns a readable MissingSessionID JSON. So the masking appears specific to the Qwen 3.8 backend route.
Control requests on the exact same key/plan (thinking with max_tokens > budget_tokens, no-thinking, tool-heavy payloads: $defs/$ref, enum/pattern, 40 tools, long system, cache_control) succeed 100% — so this is not a limits/auth/client issue and is reproducible with plain curl.
Expected: the Go gateway propagates the upstream provider's error payload for all backends, so clients surface the actual reason instead of data: {}.
User-visible symptom in opencode: frequent opaque failures on opencode-go/qwen3.8-flash with a thinking variant (variants none/low/medium/xhigh) — most turns succeed, some die in ~2s; with the payload masked, users cannot tell validation errors from outages. Related opaque-400 classes: #37771, #37937.
Plugins
One local plugin (command-log.js) — irrelevant, bug reproduces with no plugins and no opencode at all (pure curl).
OpenCode version
2.0.30 (also reproducible via plain curl/python, client-independent)
Steps to reproduce
A. Deterministic masked 400 (boundary budget == max):
curl -sN https://opencode.ai/inference/go/anthropic/v1/messages
-H "Authorization: Bearer $OPENCODE_GO_KEY"
-H "anthropic-version: 2023-06-01"
-H "x-opencode-session: ses_00000000000000000000000000"
-H "Content-Type: application/json"
-d '{"model":"qwen3.8-flash","max_tokens":1024,"stream":true,"thinking":{"type":"enabled","budget_tokens":1024},"messages":[{"role":"user","content":"hi"}]}'
=> HTTP 400, body exactly: "event: error\ndata: {}"
(same with budget > max, and same for model qwen3.8-max)
B. Control — valid combination works (thinking blocks stream fine):
same as A but "max_tokens":4096,"budget_tokens":1024 => HTTP 200 + message_stop
C. Same validation-error class on another backend is passed through readably:
claude-haiku-5-5 with max_tokens 256 + budget 1024 => HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"Upstream request failed: [invalid_request_error] "thinking..." }}
Screenshot
No response
Operating System
Ubuntu 24.04.5 LTS (Linux 6.8.0-147-generic x64)
Terminal
TERM=xterm-256color (KDE Plasma 5.27 workstation, not a server)
Activity
opencode-agent commentedon Oct 19, 2026
Thanks for the detailed report and the clean curl reproduction. I think this is a duplicate of #51530, which reports the same problem: on the OpenCode Go Anthropic Messages route,
qwen3.8-flashreturns HTTP 400 with the bodyevent: error\ndata: {}(or{"model":"qwen3.8-flash"}without streaming). The real upstream error is dropped, so opencode can only showProvider request failed with HTTP 400. That issue found it through a content-filter rejection. Yourbudget_tokens >= max_tokenscase is a deterministic way to trigger the same masking, so it would be a useful data point to add there.Possible duplicates and related issues, ordered from most to least likely:
event: error/data: {}and hides the upstream error); still open{"model":...}) for another triggerThe bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
opencode-agent commentedon Oct 20, 2026
We haven't heard back, so I'm closing this as a duplicate of #51530. Both issues are about the OpenCode Go Anthropic route for
qwen3.8-flash/qwen3.8-maxreturning HTTP 400 withevent: error/data: {}, which hides the upstream error message. Please follow #51530 for updates. Your deterministicbudget_tokens >= max_tokenscurl reproduction would be useful to add there. If your problem turns out to be different, reply here and we can reopen this.