Skip to content

Console Go (zen/go/v1): deepseek-v4-flash returns RegionError requiring China opt-in, no programmatic opt-in path #39872

Closed as not planned

Description

Summary

deepseek-v4-flash is listed in GET /zen/go/v1/models but every completion request fails with a RegionError 403 that demands a manual opt-in via a workspace link. API-only consumers (agents/gateways) cannot opt in — the error only contains a browser URL.

Repro

curl -s https://opencode.ai/zen/go/v1/chat/completions \
  -H "Authorization: Bearer <key>" -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":10}'

Response (reproduced 2026-07-31, multiple times)

{"type":"error","error":{"type":"RegionError","message":"The latest version of this model is only available hosted in China and requires explicit opt in: https://opencode.ai/workspace/wrk_01KJHRCVJTA9W5D147MYK8K5JD/go"}}

Impact

  • Model appears healthy in /models list → agents pick it as default, then every turn fails (403, non-retryable)
  • No API-surface opt-in exists; the only path is a human clicking a workspace link
  • HTTP status observed as 403 with error.type: RegionError (not a standard OpenAI-style error code)

Expected

  • Either an API opt-in mechanism (e.g. header/body flag, workspace setting changeable via API), or
  • Model excluded from /models for regions without opt-in, or
  • Error body documenting how to opt in programmatically

Environment

Activity

  1. github-actions commented on Jul 31, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is specifically about the API-only / programmatic access gap (no header/body flag to opt in, only a browser URL in the error), that angle may be unique — please clarify if #39845 doesn't fully cover your use case.

  2. MethodWhite commented on Aug 1, 2026

    @MethodWhite

    Confirming this issue with a slightly different angle that may help narrow the root cause.

    What I observed

    Two different error patterns depending on which endpoint the client is talking to:

    Pattern A — Dead endpoint (mimo v0.1.9 hardcoded path)

    mimo v0.1.9 has https://api.opencode.ai hardcoded in its binary. When deepseek-v4-flash (New) is selected, the client hits:

    POST https://api.opencode.ai/v1/chat/completions
    Authorization: Bearer <KEY>
    Content-Type: application/json
    
    {"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":10}
    

    Response:

    HTTP 200 (Cloudflare) — 9 bytes — body: "Not Found"
    

    The HTTP status is misleading: Cloudflare returns 200 OK with a placeholder body. No JSON, no headers identifying the model. Same for /v1/models, /v1/, /v2/models, etc. The endpoint is alive (DNS resolves to 172.65.90.23) but doesn't implement any API path.

    Pattern B — Region gate (opencode v1.18.11 with baseURL override)

    After pointing opencode-go to the new endpoint via baseURL: "https://opencode.ai/zen/go/v1" in opencode.jsonc, the client gets a proper error:

    POST https://opencode.ai/zen/go/v1/chat/completions
    Authorization: Bearer <KEY>
    Content-Type: application/json
    
    {"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":10}
    

    Response:

    {
      "type": "error",
      "error": {
        "type": "RegionError",
        "message": "The latest version of this model is only available hosted in China and requires explicit opt in: https://opencode.ai/workspace/wrk_01KECAP25CQMN9P8HFVCZC541H/go"
      }
    }

    HTTP 403, error body identifies the workspace and the opt-in URL. This is the path that needs fixing.

    Environment

    • mimo 0.1.9 (Bun-bundled, endpoint hardcoded — cannot be overridden from config)
    • opencode 1.18.11 (supports baseURL override in opencode.jsonc)
    • API key: valid against both endpoints (reproved by listing models on the working gateway)
    • Same key, same model ID, two clients, two failure modes

    Suggestions for the Expected section of this issue

    +1 on your "API opt-in mechanism" suggestion. A couple of more concrete ideas:

    1. Header flag: an opt-in via request header (e.g. X-Opencode-Region-Opt-In: true) for workspace-scoped keys. Lets API consumers control the routing without changing the model ID or doing browser clicks.

    2. Catalog visibility: if opt-in is required, exclude the model from GET /v1/models for callers that haven't opted in. Currently the model is in the catalog and the failure only happens on completion — agents pick it as default and fail on every turn.

    3. Error body clarity: the current error is good, but please include a machine-readable field too (e.g. "requires_opt_in": true, "opt_in_url": "...") so clients can branch programmatically and surface a useful error in their own UIs.

    4. Endpoint deprecation: the api.opencode.ai endpoint returns 200+"Not Found" on every path. If it's deprecated, please return a proper 410 Gone with a Link header pointing to the new endpoint. Returning 200 OK with body "Not Found" is a Cloudflare Worker pattern that breaks naive HTTP clients (some libs treat 200 as success and try to parse the 9-byte body as JSON).

    Workaround I'm using locally

    Switched to nvidia/deepseek-ai/deepseek-v4-flash (same model, different gateway — NVIDIA NIM) in mimo via model: "nvidia/deepseek-ai/deepseek-v4-flash" in mimocode.json. This works because the key is valid and the model is the same upstream DeepSeek release. Documented the failover in a runbook at the consumer side. Filed as ADR-001 in my own project (Noctua-C) to track the decision.

    Happy to help test any fixes on a different endpoint if you can spin up a beta.

  3. github-actions commented on Oct 1, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions