anomalyco / anomalyco/opencode

Muse Spark on /chat/completions returns misleading 500/403-country instead of pointing to /responses endpoint

Open
#47,969 1 comment 2 reactions 1 assignee View on GitHub

@jlongster is already working on this.

Since Sep 8, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

When calling muse-spark-1.2/1.3-contributor on POST /zen/go/v1/chat/completions, the gateway returns a bare {"type":"error","error":{"type":"error","message":"Internal server error"}} (HTTP 500) with no hint that these models are served only via /zen/go/v1/responses. The same models work fine on /responses with identical auth/headers. This cost multiple hours of debugging across several users (#47949, #43692, #39872, #41518) — a WrongEndpointError (or an automatic redirect) would eliminate the whole class of reports.

Related: when the same /chat/completions call is made without x-opencode-session, the gateway sometimes returns [403]: This model is not available in your country. instead of the (correct) 400 MissingSessionID. The 403 RegionError is also produced for clients that hit /chat/completions from otherwise-allowed regions — i.e. the region check appears to be evaluated before endpoint/session routing, and its error message is misleading when the actual problem is the endpoint.

Environment
  • Endpoint: https://opencode.ai/zen/go/v1 (OpenCode Go subscription, active)
  • Client: OmniRoute proxy + direct curl reproduction (no client-specific behavior involved)
  • Date: 2026-09-08, multiple hours of testing
  • Auth: sk-... Bearer key
Reproduction (single API key, same egress IP, same minute)

1. /chat/completions — fails 500 regardless of headers:

curl -s -X POST "https://opencode.ai/zen/go/v1/chat/completions" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "User-Agent: opencode" \
  -H "x-opencode-client: desktop" -H "x-opencode-project: global" \
  -H "x-opencode-session: $UUID" -H "x-opencode-request: $UUID" \
  -d '{"model":"muse-spark-1.3-contributor","messages":[{"role":"user","content":"say ok"}],"max_tokens":512}'
# → {"type":"error","error":{"type":"error","message":"Internal server error"}}  (HTTP 500)

Same result with muse-spark-1.2-contributor, with/without session headers, stream/non-stream.

2. /responses — works with the same key/IP/headers:

curl -s -X POST "https://opencode.ai/zen/go/v1/responses" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "User-Agent: opencode" \
  -H "x-opencode-client: desktop" -H "x-opencode-project: global" \
  -H "x-opencode-session: $UUID" -H "x-opencode-request: $UUID" \
  -d '{"model":"muse-spark-1.3-contributor","input":[{"role":"user","content":"say ok"}],"max_output_tokens":512,"stream":false}'
# → HTTP 200, normal response object

3. /responses without session header — correct error, good message:

{"type":"error","error":{"type":"MissingSessionID","message":"Request is missing x-opencode-session..."}}

This proves the gateway can produce precise, actionable errors — it just doesn't for the wrong-endpoint case.

4. Misleading 403 region message:

/chat/completions calls for muse models from a supported-region egress sometimes return:

{"error":{"message":"[403]: This model is not available in your country."}}

while the identical request via /responses succeeds. When the actual cause is the endpoint (and/or missing session header), surfacing a country error sends users chasing proxies/DNS for hours — see #47949 where 12 exits across 7 countries were tested, and #43692.

Expected behavior

Any of the following would fix the whole class of confusion:

  1. Best: route muse-family models to /responses automatically when they are requested on /chat/completions (the model registry already knows the required endpoint), or
  2. Return a distinct, actionable error, e.g. {"type":"WrongEndpointError","message":"muse-spark-* is only served via /zen/go/v1/responses"} (HTTP 400/404), or
  3. At minimum, document in docs/go (#Endpoints) that muse models return 500/403 country when called on /chat/completions, so the error text can be trusted.

Also worth noting: RegionError firing for /chat/completions muse calls from allowed regions (while /responses works) suggests the region gate runs before endpoint routing — moving it after endpoint resolution (or tagging its error with the resolved endpoint) would make the 403 text trustworthy.

Observed error surface summary
Call Result
muse on /chat/completions, full CLI headers + session 500 Internal server error
muse on /chat/completions, no session 403 not available in your country (misleading) or 500
muse on /responses, no session 400 MissingSessionID (good error)
muse on /responses, with session 200 (or honest rate_limit_exceeded when quota hit)
non-muse (glm-5, hy3, kimi-k3...) on /chat/completions 200 — endpoint is correct for them

All checks performed on 2026-09-08 with a paid Go subscription; happy to provide request IDs if needed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.