BerriAI/litellm · error · OpenAIError
{message}
Error message
{message} What it means
Final catch-all of the async acompletion flow (litellm/llms/openai/openai.py:947). Mirrors the sync wrapper: exceptions that are not OpenAIError are converted into one, carrying the upstream status_code (default 500), headers (taken from e.headers, falling back to e.response.headers), body, and a message read from e.message or str(e). The wrapper exists because exceptions raised inside coroutines must be normalized before they cross back into litellm's plumbing.
Source
Thrown at litellm/llms/openai/openai.py:947
return final_response_obj
except openai.UnprocessableEntityError as e:
## check if body contains unprocessable params - related issue https://github.com/BerriAI/litellm/issues/4800
if litellm.drop_params is True or drop_params is True:
data = drop_params_from_unprocessable_entity_error(e, data)
else:
raise e
# e.message
except Exception as e:
exception_response = getattr(e, "response", None)
status_code = getattr(e, "status_code", 500)
exception_body = getattr(e, "body", None)
error_headers = getattr(e, "headers", None)
if error_headers is None and exception_response:
error_headers = getattr(exception_response, "headers", None)
message = getattr(e, "message", str(e))
raise OpenAIError(
status_code=status_code,
message=message,
headers=error_headers,
body=exception_body,
)
def streaming(
self,
logging_obj,
timeout: float | httpx.Timeout,
data: dict,
model: str,
api_key: str | None = None,
api_base: str | None = None,
api_version: str | None = None,
organization: str | None = None,
client=None,
max_retries=None,View on GitHub (pinned to 77b7c6c40c)
Solutions
- Inspect e.status_code and e.message to classify: auth vs rate-limit vs context-window vs 5xx
- For context-length errors, trim messages or move to a larger-context model
- Configure num_retries and litellm.Router fallbacks for 429/5xx
- For auth errors rotate the key — retrying will not help
Defensive patterns
Strategy: try-catch
Try / catch
import asyncio
from litellm.llms.openai.common_utils import OpenAIError
async def completion_with_backoff(model, msgs, attempts=3):
for i in range(attempts):
try:
return await litellm.acompletion(model=model, messages=msgs)
except OpenAIError as e:
if e.status_code == 429 and i < attempts - 1:
await asyncio.sleep(2 ** i)
continue
if e.status_code >= 500 and i < attempts - 1:
await asyncio.sleep(1)
continue
raise Prevention
- Check prompt token counts before sending to avoid 400 context_length_exceeded
- Use asyncio-friendly exponential backoff; never sleep synchronously in event loops
- Configure Router allowed_fails and fallbacks so 429/5xx failover is automatic
- Rotate keys on 401 immediately — retries amplify outage duration
When it happens
Trigger: Async completions failing upstream: 400 context_length_exceeded, 429 rate limit, 401 auth, provider 5xx; asyncio/httpx transport errors surfaced as synthetic 500s carrying the transport message.
Common situations: Async fan-out workers tripping rate limits; expired keys in long-lived async clients; prompts exceeding the model context window; provider regional incidents returning 5xx.
Related errors
- err.response.text
- {response.aread()}
- Failed to fetch file '{file_path}': {e}
- Failed to list files in '{directory_path}': {e}
- Error retrieving usage data: {e}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/70f3f2c78912b649.
Report an issue: GitHub.