Skip to content

fix: keep the provider's status and meaning in upstream errors - #9

Merged
Marketen merged 1 commit into
mainfrom
fix/honest-upstream-errors
Oct 15, 2026
Merged

Marketen merged 1 commit into
mainfrom
fix/honest-upstream-errors

Conversation

@Marketen

Copy link
Copy Markdown
Contributor

Summary

Every provider 4xx came back as 502 provider_unavailable, so a request the provider rejected looked like an outage, and so did our own provider credential failures.

Provider answer Gateway response
400, 404, 422 and other 4xx same status, provider_rejected_request
401, 402, 403 502 provider_configuration_error (Nexus's provider account, not the caller's key)
429 429 provider_rate_limited, with a valid Retry-After
503 503 provider_unavailable (unchanged)
504 504 provider_timeout
other 5xx same status, provider_error
  • Errors also include origin (gateway or upstream) and, when known, upstream_status. Other diagnostic details stay internal.
  • A configured fallback provider is tried only after a 429 or 5xx.

Compatibility

  • Clients now see 4xx statuses where they used to see 502, so they stop retrying requests the provider rejected.
  • Generic provider 5xx use the code provider_error instead of provider_unavailable.

Tests

  • Unit tests cover the status mapping, Retry-After validation, the new error fields and the fallback rule.
  • Checked end to end against real providers: an image sent to a text-only model returns 400 provider_rejected_request, and an invalid provider key returns 502 provider_configuration_error.

🤖 Generated with Claude Code

Every provider 4xx came back as 502 provider_unavailable, so a request the
provider rejected looked like an outage, and our own provider credential or
billing failures looked the same as both.

- Provider 4xx keeps its status, code provider_rejected_request.
- Provider 401/402/403 become 502 provider_configuration_error: they concern
  Nexus's provider account, not the caller's key.
- 429 becomes provider_rate_limited and keeps a validated Retry-After.
- 504 becomes provider_timeout; other 5xx keep their status as provider_error.
- Errors carry origin (gateway or upstream) and upstream_status. Other
  diagnostic metadata stays internal.
- A configured fallback provider is tried only after 429 or 5xx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Marketen
Marketen merged commit 27bdd2e into main Oct 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant