BerriAI/litellm · error · APIError
APIError: {exception_provider} - {error_str}
Error message
APIError: {exception_provider} - {error_str} What it means
This is LiteLLM's catch-all APIError for upstream HTTP exceptions that have a status code but do not match any specific mapping (400/401/403/429/503/504 etc.). The original status code is preserved on the raised exception, so inspect exception.status_code to understand the real failure.
Source
Thrown at litellm/litellm_core_utils/exception_mapping_utils.py:2145
)
elif original_exception.status_code == 503:
raise ServiceUnavailableError(
message=f"ServiceUnavailableError: {exception_provider} - {error_str}",
model=model,
llm_provider=custom_llm_provider,
response=getattr(original_exception, "response", None),
litellm_debug_info=extra_information,
)
elif original_exception.status_code == 504: # gateway timeout error
raise Timeout(
message=f"Timeout Error: {exception_provider} - {error_str}",
model=model,
llm_provider=custom_llm_provider,
litellm_debug_info=extra_information,
exception_status_code=original_exception.status_code,
)
else:
raise APIError(
status_code=original_exception.status_code,
message=f"APIError: {exception_provider} - {error_str}",
llm_provider=custom_llm_provider,
model=model,
request=getattr(original_exception, "request", None),
litellm_debug_info=extra_information,
)
else:
# if no status code then it is an APIConnectionError: https://github.com/openai/openai-python#handling-errors
raise APIConnectionError(
message=f"APIConnectionError: {exception_provider} - {error_str}",
llm_provider=custom_llm_provider,
model=model,
litellm_debug_info=extra_information,
request=httpx.Request(method="POST", url="https://api.openai.com/v1/"),
)
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Catch APIError and branch on e.status_code to get the true cause.
- For 5xx codes, retry with backoff; for 4xx codes, fix the request/billing/config.
- Print the full message — it embeds the provider name and the original error string.
- Check the provider's dashboard/logs for the corresponding request.
Example fix
# before
resp = litellm.completion(model=..., messages=msgs)
# after
try:
resp = litellm.completion(model=..., messages=msgs)
except litellm.APIError as e:
if e.status_code and e.status_code >= 500:
raise # transient, retry upstream
raise Defensive patterns
Strategy: try-catch
Try / catch
try {
await litellm.completion(...);
} catch (e) {
if (e instanceof litellm.APIError) {
const sc = e.status_code;
if (sc >= 500) { /* retry */ } else { /* fix request/billing, do not retry */ }
}
} Prevention
- Always branch on e.status_code rather than the message text.
- Treat 4xx APIError as permanent and 5xx as retryable.
- Log the full message once — it embeds provider and upstream error string.
When it happens
Trigger: Any completion call whose upstream error has an unmapped status code — e.g. 402 (payment required), 409, 422, 499, 500, or non-standard codes returned by OpenAI-compatible providers.
Common situations: Billing issues (402), internal server errors (500) at third-party OpenAI-compatible endpoints, provider-specific validation codes, or new status codes not yet mapped by litellm.
Related errors
- err.response.text
- err.response.text
- {err.response.text}
- Failed to transform Braintrust response: {str(e)}
- Failed to retrieve file {file_id} from provider: {str(e)}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/f67425574d591298.
Report an issue: GitHub.