BerriAI/litellm · error · OpenAIError

{raw_response.text}

Error message

{raw_response.text}

What it means

After litellm sends an image edit request (images/edits endpoint), it tries raw_response.json(); if the body is not valid JSON it raises OpenAIError with the raw body text as the message and the upstream HTTP status code. The wrapper exists precisely because non-JSON error bodies (HTML gateways, empty replies) would otherwise produce an opaque JSONDecodeError.

Source

Thrown at litellm/llms/openai/image_edit/transformation.py:152

                mask_content_type: Final[str] = ImageEditRequestUtils.get_image_content_type(_mask)
                if isinstance(_mask, BufferedReader):
                    files_list.append(("mask", (_mask.name, _mask, mask_content_type)))
                else:
                    files_list.append(("mask", ("mask.png", _mask, mask_content_type)))

        return data_without_files, files_list

    def transform_image_edit_response(
        self,
        model: str,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
    ) -> ImageResponse:
        """No transform applied since outputs are in OpenAI spec already"""
        try:
            raw_response_json: Final = raw_response.json()
        except Exception:
            raise OpenAIError(message=raw_response.text, status_code=raw_response.status_code)
        return ImageResponse(**raw_response_json)

    def validate_environment(
        self,
        headers: dict,
        model: str,
        api_key: str | None = None,
        litellm_params: dict | None = None,
        api_base: str | None = None,
    ) -> dict:
        api_key = api_key or litellm.api_key or litellm.openai_key or get_secret_str("OPENAI_API_KEY")
        headers.update(
            {
                "Authorization": f"Bearer {api_key}",
            }
        )
        return headers

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read OpenAIError.status_code and the message body: HTML like '502 Bad Gateway' implicates a proxy/CDN, so retry after the intermediary recovers
  2. If a custom api_base is set, verify that endpoint returns JSON errors in OpenAI format (curl it directly and inspect Content-Type)
  3. For large images, compress or reduce size to avoid truncated uploads producing non-JSON truncation errors
  4. Retry transient 5xx gateway responses with exponential backoff; the request itself is usually valid

Example fix

# before
resp = litellm.image_edit(model="gpt-image-1", image=open("cat.png","rb"), prompt="add a hat")
# raises OpenAIError whose message is an HTML error page

# after
from litellm.exceptions import OpenAIError

try:
    resp = litellm.image_edit(model="gpt-image-1", image=open("cat.png","rb"), prompt="add a hat")
except OpenAIError as e:
    if getattr(e, "status_code", 0) >= 500:
        time.sleep(2)
        resp = litellm.image_edit(model="gpt-image-1", image=open("cat.png","rb"), prompt="add a hat")
    else:
        raise
Defensive patterns

Strategy: try-catch

Validate before calling

import os

# avoid the truncated/gateway path: validate the input file before the call
path = "edit.png"
assert os.path.getsize(path) > 0, "image file is empty"
with open(path, "rb") as f:
    head = f.read(8)
assert head[:8] == b"\x89PNG\r\n\x1a\n" or head[:3] == b"\xff\xd8\xff", "not a PNG/JPEG"

Try / catch

from litellm.exceptions import OpenAIError

try:
    resp = litellm.image_edit(model="gpt-image-1", image=img, prompt=p)
except OpenAIError as e:
    body = str(getattr(e, "message", e)) or ""
    if getattr(e, "status_code", 0) >= 500 or "<" in body[:1]:  # gateway HTML page
        time.sleep(2)
        resp = litellm.image_edit(model="gpt-image-1", image=img, prompt=p)
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm.image_edit() (gpt-image-1 / dall-e-2 edits) when the endpoint returns a non-JSON body: 502/504 HTML error pages from proxies or Cloudflare, empty responses from truncated uploads, malformed multipart payloads rejected by an intermediary, or OpenAI-compatible gateways that return plain-text errors.

Common situations: Self-hosted gateways or corporate proxies in front of api.openai.com returning HTML on overload; oversized image uploads getting cut off; custom OpenAI-compatible providers whose error responses are not JSON; brief outages where a CDN serves an error page instead of the API.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/e566d967e1d3c54b. Report an issue: GitHub.