BerriAI/litellm · error · OpenAIError

error_message or raw_response.text

Error message

error_message or raw_response.text

What it means

Raised as `OpenAIError` on the ChatGPT Responses path when the SSE body could not be parsed into a completed response. `error_message` comes from the SSE extraction helper; if it is empty the raw response text is used instead, and the HTTP status of the original response is preserved. It means the streaming payload was malformed, contained an error event, or the endpoint returned an error page rather than events.

Source

Thrown at litellm/llms/chatgpt/responses/transformation.py:127

        raw_response: Any,
        logging_obj: Any,
    ):
        body_text: Final = raw_response.text or ""
        if not self._should_parse_as_sse(raw_response=raw_response, body_text=body_text):
            return super().transform_response_api_response(
                model=model,
                raw_response=raw_response,
                logging_obj=logging_obj,
            )

        logging_obj.post_call(
            original_response=raw_response.text,
            additional_args={"complete_input_dict": {}},
        )

        completed_response, error_message = self._extract_completed_response_from_sse(body_text=body_text)
        if completed_response is None:
            raise OpenAIError(
                message=error_message or raw_response.text,
                status_code=raw_response.status_code,
            )

        self._attach_response_headers(completed_response=completed_response, raw_response=raw_response)
        return completed_response

    def _should_parse_as_sse(self, raw_response: Any, body_text: str) -> bool:
        content_type: Final = (raw_response.headers or {}).get("content-type", "")
        if "text/event-stream" in content_type.lower():
            return True
        trimmed_body: Final = body_text.lstrip()
        return bool(
            trimmed_body.startswith("event:")
            or trimmed_body.startswith("data:")
            or "\nevent:" in body_text
            or "\ndata:" in body_text
        )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the message body — it contains either the SSE error text or the raw response, which names the real problem.
  2. Retry once; truncated streams are often transient network artifacts.
  3. Disable stream buffering on intermediate proxies (`X-Accel-Buffering: no`, disable response buffering) for `text/event-stream`.
  4. Upgrade litellm if the ChatGPT responses event schema changed; if persistent, capture the raw body and report it.

Example fix

// before
resp = litellm.responses(model="chatgpt/gpt-4o", input="hi", stream=True)

// after (guard and inspect)
try:
    resp = litellm.responses(model="chatgpt/gpt-4o", input="hi", stream=True)
except litellm.llms.openai.common_utils.OpenAIError as e:
    logger.error("responses failed status=%s body=%s", e.status_code, e.message)
    raise
Defensive patterns

Strategy: retry

Try / catch

try:
    resp = litellm.responses(model="chatgpt/gpt-4o", input="hi", stream=True)
except OpenAIError as e:
    log.error("responses SSE parse failed status=%s body=%.500s", e.status_code, e.message)
    if e.status_code in (502, 503, 504):
        backoff_and_retry_once()
    else:
        raise

Prevention

When it happens

Trigger: Calling the chatgpt provider's responses endpoint and receiving a non-SSE error body (HTML block page, JSON error) that reaches the SSE parser, or a stream that ends before a terminal/completed event arrives (proxy truncation, connection cut mid-stream).

Common situations: Corporate proxies buffering or truncating event-streams; model/parameter combos the ChatGPT backend rejects mid-stream; account/session errors surfacing as error events; outdated litellm SSE parsing against a changed event schema.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/fd2e5fa192dbcb07. Report an issue: GitHub.