BerriAI/litellm · error · OpenAIError
{e} Original Response: {response.text}
Error message
{e}
Original Response: {response.text} What it means
Error branch in streaming() (litellm/llms/openai/openai.py:1101) taken when the request failed but an httpx response with .text exists: litellm raises OpenAIError with message '<exception>\n\nOriginal Response: <response.text>' plus the upstream status, headers and body. The appended Original Response is the raw error body — typically a proxy's HTML error page or the provider's JSON error object — and is the primary diagnostic.
Source
Thrown at litellm/llms/openai/openai.py:1101
## 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
except (
Exception
) as e: # need to exception handle here. async exceptions don't get caught in sync functions.
if isinstance(e, OpenAIError):
raise e
error_headers = getattr(e, "headers", None)
status_code = getattr(e, "status_code", 500)
error_response = getattr(e, "response", None)
exception_body = getattr(e, "body", None)
if error_headers is None and error_response:
error_headers = getattr(error_response, "headers", None)
if response is not None and hasattr(response, "text"):
raise OpenAIError(
status_code=status_code,
message=f"{e}\n\nOriginal Response: {response.text}",
headers=error_headers,
body=exception_body,
)
else:
if type(e).__name__ == "ReadTimeout":
raise OpenAIError(
status_code=408,
message=f"{type(e).__name__}",
headers=error_headers,
body=exception_body,
)
elif hasattr(e, "status_code"):
raise OpenAIError(
status_code=getattr(e, "status_code", 500),
message=str(e),
headers=error_headers,View on GitHub (pinned to 77b7c6c40c)
Solutions
- Read the 'Original Response:' section — HTML means proxy/routing problem, JSON means provider error with a code
- Fix api_base so it resolves to the real /v1/chat/completions route
- If it is a 502/504 from a proxy, fix or bypass the proxy
- Map the status_code plus the JSON error code to the concrete fix (key, model, quota)
Example fix
# before litellm.completion(model='gpt-4o', messages=msgs, stream=True, api_base='https://gw.internal') # after litellm.completion(model='gpt-4o', messages=msgs, stream=True, api_base='https://gw.internal/v1')
Defensive patterns
Strategy: try-catch
Validate before calling
import httpx
def stream_endpoint_ok(api_base: str, api_key: str) -> bool:
r = httpx.post(
f'{api_base.rstrip("/")}/chat/completions',
headers={'Authorization': f'Bearer {api_key}'},
json={'model': 'ping', 'messages': [{'role': 'user', 'content': 'ping'}], 'stream': True},
timeout=15,
)
return r.status_code == 200 and 'text/event-stream' in r.headers.get('content-type', '') Try / catch
from litellm.llms.openai.common_utils import OpenAIError
try:
stream = litellm.completion(model=m, messages=msgs, stream=True)
for chunk in stream:
process(chunk)
except OpenAIError as e:
if 'Original Response' in e.message:
if '<html' in e.message.lower():
alert_ops('proxy error page returned — check api_base path and upstream health')
raise Prevention
- Assert content-type is text/event-stream in endpoint smoke tests
- Keep the api_base path convention in a single config constant
- Alert on HTML bodies — they always indicate path/proxy misconfiguration, not model errors
- Include the Original Response section in error reports; it is the raw upstream diagnostic
When it happens
Trigger: Streaming calls where the server answers non-200 with a body: nginx/traefik 502/504 HTML pages, OpenAI JSON errors (invalid_api_key, model_not_found), gateways returning HTML 404s because the api_base path is wrong, WAFs intercepting streaming POSTs.
Common situations: api_base missing /v1 so the path 404s with HTML; upstream LLM unavailable behind a load balancer; auth failures; corporate proxies blocking SSE.
Related errors
- {response.read()}
- {response.aread()}
- OVHCloud Error: {}
- A2A send_message_streaming failed: no response received afte
- api_base is required for Pydantic AI agents
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/841c359ab21a1649.
Report an issue: GitHub.