LLM error decoder
Paste an LLM API error and see what happened, whether to retry and what to fix — for Salyro, OpenAI, Anthropic and Gemini, and what it becomes through Salyro.
What it does
Paste the body of a failed response, or an error as it arrived inside a stream, and the decoder gives it back as three answers:
- What happened — the family and the meaning of the error;
- Retry? — yes, not as it is, depends (on what the provider reported), or unknown;
- What to fix — where a source says.
It reads Salyro's errors, OpenAI's (and OpenAI-compatible ones), Anthropic's and Gemini's, told apart by the shape of the body. When the HTTP status is known, it also says what the error becomes through Salyro. A status the body does not carry — OpenAI's does not — can be typed beside it. When the body has its own, as Gemini's does, the body's is used, and a typed one that differs is noted.
Everything runs in your browser: nothing you paste is sent anywhere.
Try it: Salyro invalid_api_key, Anthropic overloaded inside a stream, or Gemini INVALID_ARGUMENT.
Salyro's errors
A Salyro error is read from the gateway's own contract: every code's type and HTTP status, and the sentence the gateway writes for it, for the Public API and for Behavior runs. The card places the code in the families of the Errors page — authentication, rate limit exceeded, normalised provider error, and a parameter the provider does not support — and gives the retry rule the API reference gives its status: a 400 is changed, a 401 fixed, a 429 backed off and retried, a 5xx usually retried with backoff.
Two codes deserve a second look:
provider_authentication_failedis not your key. The provider refused the gateway's stored credential; your Salyro key is fine, and the credential is reconnected in the dashboard.provider_rate_limit_exceededis the provider's limit, not your key's. It is still a429, so back off and retry.
What a provider's error becomes through Salyro
Salyro never passes a provider's error body on. It answers with its own code, chosen by the provider's HTTP status:
| Upstream status | Salyro code |
|---|---|
| 400, 422 | invalid_request |
| 401, 403 | provider_authentication_failed |
| 408, 504 | provider_timeout |
| 429 | provider_rate_limit_exceeded |
| anything else | provider_error |
The table is read from the gateway's own mapping. A timeout on Salyro's side is provider_timeout too, and an unreachable routing layer is service_unavailable.
A failure after a stream has started cannot change the status: the 200 has already been sent. It arrives as one error frame instead, and the stream ends without its end marker. The frame carries the code the table gives when the failure reports its status, provider_timeout when Salyro's own clock ran out, and provider_error — "The upstream model provider failed part-way through the answer." — when the provider failed and reported no status. An error pasted from a stream is described that way.
Providers' errors
- Anthropic: read by the
error.typeof its body, from its errors page on platform.claude.com — the status, the meaning and what to do for each type. Retry is "yes" for the failures its page says the official SDKs retry — connection errors, rate limits and 5xx server errors — and "not as it is" for the rest. - OpenAI: its error-codes guide could not be read, so what each
typeandcodemeans isunknown, and so is whether to retry it. What is known is its Python SDK's table: which error class each status raises, and which statuses the SDK retries by default (408, 409, 429 and 5xx). The card says what the SDK does with the status — never that the error will clear: an SDK that retries every 429 retries aninsufficient_quota429 too. - Gemini: read by the status name in its body, from
google.rpc.Code— the canonical codes Google's APIs report, with their HTTP mapping and, for some, whether to retry, in the definition's own words:UNAVAILABLEis retried with a backoff,ABORTEDat a higher level — the sequence the call belongs to, not the call alone. Gemini's own troubleshooting page could not be read, so what each status means for the Gemini API in particular isunknown. - xAI: its page could not be read. Its bodies share OpenAI's shape and are read as such.
What it does not know
- Why your request failed. It reads the body you paste; it does not see the request or call any API.
- What a provider says where its page could not be read — shown as
unknown, never guessed. - Who sent an OpenAI-shaped body. Salyro's errors share OpenAI's envelope; a body with every Salyro marker is read as Salyro's, and the card says OpenAI's is possible too.
FAQ
Should I retry a 429?
Yes, after waiting. Salyro's own rate limit (rate_limit_exceeded) and Anthropic's rate limits send retry-after; read it with the rate-limit headers decoder. A 429 from Anthropic without retry-after is a spend cap, and keeps failing until access resumes.
Why does Salyro return 502 when the provider said 401?
Because it was the gateway's provider credential that was refused, not your key. A 401 would tell your client to stop and rotate a key that works.
Why does my error arrive with a 200?
It happened after the stream started. The status had already been sent; the error arrives as the stream's last frame. Paste the stream into the SSE stream reconstructor to see what came before it.
Sources
Salyro's codes, sentences and upstream mapping are the gateway's own, from its shared package. Anthropic's errors are quoted from its errors page on platform.claude.com. OpenAI's are from the README of its Python SDK (openai/openai-python), and Gemini's statuses from google/rpc/code.proto (googleapis/googleapis), both on GitHub.
Where the numbers come from
- Facts about models and providers that are not in that catalogue carry their own source and the date they were checked, and are shown as unknown where no reliable source exists.
