Summary
When the upstream API key is invalid or expired, every fallback model is tried serially before returning a 502 error. Since all models from the same provider share the same API key, they all fail with the identical "Invalid API key" error — but the proxy wastes time retrying each one.
Evidence (from v0.2.2 logs)
time=2026-06-02T19:59:03.621 level=INFO msg="routing request" scenario=fast model=qwen3.6-plus provider=opencode-go
time=2026-06-02T19:59:04.303 level=WARN msg="anthropic streaming failed" model=qwen3.6-plus error="...Invalid API key..."
time=2026-06-02T19:59:04.303 level=INFO msg="attempting streaming model" model=qwen3.5-plus provider=opencode-go
time=2026-06-02T19:59:04.580 level=WARN msg="anthropic streaming failed" model=qwen3.5-plus error="...Invalid API key..."
time=2026-06-02T19:59:04.580 level=INFO msg="attempting streaming model" model=minimax-m2.5 provider=opencode-go
time=2026-06-02T19:59:04.852 level=WARN msg="anthropic streaming failed" model=minimax-m2.5 error="...Invalid API key..."
time=2026-06-02T19:59:04.852 level=ERROR msg="sending stream error" message="all upstream models failed"
This pattern repeats for every request — all 3 streaming fallbacks fail identically before the proxy gives up. For non-streaming requests, the same happens across all 3 fallback attempts.
Expected behavior
Auth errors (401/403) are non-retryable by nature — no fallback model will work because they all use the same credentials. The proxy should:
- Detect auth errors immediately
- Skip the remaining fallback chain
- Return a clear error to the client ("Invalid API key — please check your OPENCODE_API_KEY")
This is similar to issue #101 which fixed the same pattern for usage-limit (429) errors — auth errors deserve the same fast-fail treatment.
Environment
Summary
When the upstream API key is invalid or expired, every fallback model is tried serially before returning a 502 error. Since all models from the same provider share the same API key, they all fail with the identical
"Invalid API key"error — but the proxy wastes time retrying each one.Evidence (from v0.2.2 logs)
This pattern repeats for every request — all 3 streaming fallbacks fail identically before the proxy gives up. For non-streaming requests, the same happens across all 3 fallback attempts.
Expected behavior
Auth errors (401/403) are non-retryable by nature — no fallback model will work because they all use the same credentials. The proxy should:
This is similar to issue #101 which fixed the same pattern for usage-limit (429) errors — auth errors deserve the same fast-fail treatment.
Environment