Skip to content

[bug] Auth errors (401/403) should short-circuit the fallback chain #108

Description

@t0anh

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:

  1. Detect auth errors immediately
  2. Skip the remaining fallback chain
  3. 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

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions