Skip to content

[Provider API] Region-restricted models return 403 "Authentication failed" while the same API correctly returns MODEL_NOT_IN_PLAN for plan gates #930

Description

@putrakoe

Summary

The Provider API does not map regional restrictions to a useful error. For region-blocked models it
returns a credential-shaped error, while the CLI reports the real cause for the same account, and
while the API itself handles a plan gate correctly.

Same account, same endpoint, same key, only model differs:

  • meta/muse-spark-1.2 -> 403 {"error":{"message":"Authentication failed. Please check your credentials.","type":"permission_error"}}
  • meta/muse-spark-1.3-contributor -> same auth-shaped 403
  • meta/muse-spark-1.1 -> 403 {"error":{"message":"MODEL_NOT_IN_PLAN: Muse Spark 1.1 available in Pro and above plans or extra on demand usage","type":"permission_error","code":"FORBIDDEN"}}
  • deepseek/deepseek-v4.1-flash -> 200 OK

CLI 1.65.2, same account:
cmd -p "hi" -m meta/muse-spark-1.3-contributor
-> Error: 403 meta/muse-spark-1.3-contributor is not available in your region per Meta's Geographic
Use Policy. https://ai.developer.meta.com/legal/geographic-use-policy (exit code 4)

So the region reason is known internally, the plan gate is already reported correctly, but the API
collapses the regional case into "Authentication failed". Clients that only use the Provider API
cannot distinguish a region block from bad credentials, which cost significant debugging time.

Expected Behavior

Region-blocked models should return a distinct, actionable 403, consistent with the CLI, e.g.:

403 {"error":{
"message":"meta/muse-spark-1.3-contributor is not available in your region per Meta's Geographic Use Policy.",
"type":"permission_error",
"code":"MODEL_NOT_AVAILABLE_IN_REGION"}}

Plan gates must keep returning MODEL_NOT_IN_PLAN (already correct for muse-spark-1.1), and
401 authentication_error "Invalid 'Authorization' header or token." stays reserved for missing or
invalid credentials.

Actual Behavior

Provider API, region-blocked model:
HTTP/1.1 403 Forbidden
{"error":{"message":"Authentication failed. Please check your credentials.","type":"permission_error"}}
x-trace-id: fac34145854a6ab16cd08ad2c905a1fc

Provider API, plan gate (same key — proof the mapping can be correct):
HTTP/1.1 403 Forbidden
{"error":{"message":"MODEL_NOT_IN_PLAN: Muse Spark 1.1 available in Pro and above plans or extra on demand usage","type":"permission_error","code":"FORBIDDEN"}}

CLI 1.65.2, region-blocked model (the correct reason the API is missing):
Error: 403 meta/muse-spark-1.3-contributor is not available in your region per Meta's Geographic Use
Policy. Read more at https://ai.developer.meta.com/legal/geographic-use-policy. Please try a different model.
exit code: 4

Control:
curl ... model=deepseek/deepseek-v4.1-flash -> 200 OK (x-trace-id: b204db5162a803c8ccb910c9e432aa8e)
cmd -p "reply with exactly: OK" -m deepseek/deepseek-v4.1-flash -> "OK", exit 0

Steps to reproduce the issue

  1. cmd -p "hi" -m meta/muse-spark-1.3-contributor -> region error, exit 4 (correct)
  2. curl ... -d '{"model":"meta/muse-spark-1.3-contributor", ...}' -> 403 "Authentication failed" (wrong)
  3. curl ... -d '{"model":"meta/muse-spark-1.1", ...}' -> 403 MODEL_NOT_IN_PLAN (correct)
  4. curl ... -d '{"model":"deepseek/deepseek-v4.1-flash", ...}' -> 200 OK

Command Code Version

1.65.2

Operating System

Windows

Terminal/IDE

VS Code + curl 8.21.0 (Windows, Schannel)

Shell

PowerShell 5.1

Session file (optional)

N/A — reproduced headlessly (cmd -p), exit codes 4 and 0

Fix prompt (optional)

The Provider API collapses regional model restrictions into an authentication error, while the
same API reports plan gates correctly and the CLI knows the real reason.

Reproduce

  1. CLI 1.65.2:
    cmd -p "hi" -m meta/muse-spark-1.3-contributor
    -> exit 4
    Error: 403 meta/muse-spark-1.3-contributor is not available in your region per Meta's
    Geographic Use Policy. Read more at https://ai.developer.meta.com/legal/geographic-use-policy.
    Please try a different model.

  2. Provider API, same model, same account:
    POST /provider/v1/chat/completions
    -> 403 {"error":{"message":"Authentication failed. Please check your credentials.","type":"permission_error"}}

  3. Provider API, plan gate (same key) — already correct, must not regress:
    meta/muse-spark-1.1
    -> 403 {"error":{"message":"MODEL_NOT_IN_PLAN: Muse Spark 1.1 available in Pro and above plans
    or extra on demand usage","type":"permission_error","code":"FORBIDDEN"}}

Where it lives

  • The Provider API error-mapping layer that turns gate/upstream failures into the OpenAI error
    envelope for /provider/v1/chat/completions and /provider/v1/responses.
  • The regional check already produces a user-facing message for the CLI — reuse that same source of
    truth as the mapped API message instead of a generic auth fallback.

Required behaviour

  1. Region restriction -> HTTP 403 with a distinct code and the policy message, e.g.
    {"error":{"message":" is not available in your region per Meta's Geographic Use Policy.
    ","type":"permission_error","code":"MODEL_NOT_AVAILABLE_IN_REGION"}}
  2. Keep existing plan gates as-is (403 MODEL_NOT_IN_PLAN) — do not change muse-spark-1.1 behaviour.
  3. Reserve 401 authentication_error "Invalid 'Authorization' header or token." strictly for missing
    or invalid credentials; never use an auth message for an entitlement/region decision.
  4. Keep the mapping provider-agnostic: the same rule should apply to any future region-restricted
    model, not just Meta's.

Tests to add

  • valid key + meta/muse-spark-1.3-contributor -> 403 with code MODEL_NOT_AVAILABLE_IN_REGION
    (must NOT contain "Authentication failed")
  • valid key + meta/muse-spark-1.1 -> 403 MODEL_NOT_IN_PLAN (unchanged)
  • valid key + deepseek/deepseek-v4.1-flash -> 200
  • missing/invalid key -> 401 authentication_error
  • regression test asserting the Provider API reason matches the CLI reason for the same
    model/region, so the two surfaces cannot diverge again
  • docs update: add the region-restricted models to the "Geo model limits" list and document the
    new error code on the Provider API errors table

Manual verification

  • curl valid key + meta/muse-spark-1.2 -> region code/message
  • cmd -p "hi" -m meta/muse-spark-1.2 -> same reason, exit 4
  • curl valid key + deepseek/deepseek-v4.1-flash -> 200

Additional context

Environment

  • Provider API: https://api.commandcode.ai/provider/v1
  • Command Code CLI: 1.65.2 (Windows), headless via cmd -p
  • curl 8.21.0 (Windows, Schannel); Windows 11 (build 26200)
  • Client region: Indonesia; requests egress via Cloudflare HKG edge
    (CF-RAY a4087d2c7de25df6-HKG / a4088b202c4f2119-HKG)
  • Account: putrakoe — plan GOAT (inferred: google/gemini-3.8-flash "GOAT and above" -> 200;
    google/gemini-3.5-flash-lite "Pro and above" -> 403 MODEL_NOT_IN_PLAN)
  • No proxy, no TLS interception, no x-cmd-zdr
  • Keys tested (masked): prefix user_5GUYVTfML… (len 93, API/VS Code) and
    prefix user_4onCMncue… (len 93, CLI credential cli-2026-09-10). Both behave identically.

Full gate matrix (same account, same keys, same endpoint)

Model CLI 1.65.2 Provider API Reality
meta/muse-spark-1.3-contributor 403 region msg (exit 4) 403 permission_error "Authentication failed" region block
meta/muse-spark-1.3 403 region msg (exit 4) 403 permission_error "Authentication failed" region block
meta/muse-spark-1.2-contributor 403 region msg (exit 4) 403 permission_error "Authentication failed" region block
meta/muse-spark-1.2 403 region msg (exit 4) 403 permission_error "Authentication failed" region block
meta/muse-spark-1.1 403 MODEL_NOT_IN_PLAN (exit 4) 403 MODEL_NOT_IN_PLAN (code FORBIDDEN) plan gate — API correct
deepseek/deepseek-v4.1-flash OK (exit 0) 200 OK works
xiaomi/mimo-v2.6-flash — 200 OK works
z-ai/glm-5.3-flash — 200 OK works
xai/grok-4.5 — 200 OK works
google/gemini-3.8-flash — 200 OK works

Key observation: the API maps the plan gate correctly (muse-spark-1.1) but maps the region gate to
an authentication error (muse-spark-1.2 / 1.3 / *-contributor). The CLI has the correct reason for
the same requests, so this is a mapping gap, not missing information.

Verbatim evidence

Provider API, region-blocked model:
HTTP/1.1 403 Forbidden
{"error":{"message":"Authentication failed. Please check your credentials.","type":"permission_error"}}
x-trace-id: fac34145854a6ab16cd08ad2c905a1fc (2026-09-25T07:59:21Z, CF-RAY a4087d2c7de25df6-HKG)
x-trace-id: a2477a186eaaa50c6f1d7d2cbcf170f2 (2026-09-25T08:08:52Z, models list call, 200)

CLI, region-blocked model:
$ cmd -p "hi" -m meta/muse-spark-1.3-contributor
Error: 403 meta/muse-spark-1.3-contributor is not available in your region per Meta's Geographic
Use Policy. Read more at https://ai.developer.meta.com/legal/geographic-use-policy. Please try a
different model.
exit code: 4

CLI, control (same account/key):
$ cmd -p "Reply with exactly: DEEPSEEK OK" -m deepseek/deepseek-v4.1-flash
DEEPSEEK OK
exit code: 0
$ cmd -p "Berapa 17 x 3? Jawab hanya angkanya." -m deepseek/deepseek-v4.1-flash
51
exit code: 0

Provider API, control:
curl ... -d '{"model":"deepseek/deepseek-v4.1-flash", ...}' -> 200 OK
x-trace-id: b204db5162a803c8ccb910c9e432aa8e

cmd --list-models lists all five meta/muse-spark-* entries with no region annotation, so the
restriction is only discoverable at request time.

Documentation references

Timeline on this account for meta/muse-spark-1.3-contributor

  • 2026-09-03 streamed successfully
  • 2026-09-22 "You have insufficient credits to make this request."
  • 2026-09-25 403 — CLI reports the regional restriction; Provider API reports "Authentication failed"

Requests

  1. Map regional restrictions to a distinct Provider API error (suggested code
    MODEL_NOT_AVAILABLE_IN_REGION) with the same message the CLI already shows.
  2. Keep MODEL_NOT_IN_PLAN behaviour unchanged (currently correct).
  3. Add the region-restricted models to the "Geo model limits" documentation list, with the
    affected regions.
  4. Document the region error code on the Provider API errors table so clients can distinguish
    credential, plan, and region failures.

Available on request: full transcripts for every request above, additional trace IDs, and the full
API keys through a private channel for account lookup. Keys are intentionally masked here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions