BerriAI/litellm · error · Exception

Error apply_db_fixes: {str(e)}

Error message

Error apply_db_fixes: {str(e)}

What it means

In the OpenAI image-edit transformation, the provider's HTTP response body is expected to be JSON matching the ImageResponse schema. If raw_response.json() throws (body is HTML, empty, or malformed), the handler raises OpenAIError with the raw body text as the message and the HTTP status as status_code. The literal 'raw_response.text' is the fallback message source - meaning the body was not parseable JSON.

Source

Thrown at db_scripts/update_unassigned_teams.py:33

            SET team_id = (
                SELECT vt.team_id
                FROM "LiteLLM_VerificationToken" vt
                WHERE vt.token = "LiteLLM_SpendLogs".api_key
            )
            WHERE team_id IS NULL
            AND EXISTS (
                SELECT 1
                FROM "LiteLLM_VerificationToken" vt
                WHERE vt.token = "LiteLLM_SpendLogs".api_key
            );
        """
        response = await db.query_raw(sql_query)
        print(
            "Updated unassigned teams, Response=%s",
            response,
        )
    except Exception as e:
        raise Exception(f"Error apply_db_fixes: {str(e)}")
    return

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Catch OpenAIError and log .status_code and .message (the raw body) to see what the server actually returned.
  2. If using a custom api_base, curl the image edit endpoint directly and confirm it returns OpenAI-spec JSON.
  3. Bypass corporate proxies or add proper exceptions for api.openai.com.
  4. Retry transient 5xx non-JSON responses with backoff; if persistent, check status.openai.com.

Example fix

# before
img = litellm.image_edit(model="gpt-image-1", image=[...], prompt="...")

# after
try:
    img = litellm.image_edit(model="gpt-image-1", image=[...], prompt="...")
except litellm.exceptions.OpenAIError as e:
    logger.error("image_edit failed %s: %s", e.status_code, str(e.message)[:500])
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

def looks_like_openai_endpoint(api_base: str) -> bool:
    return api_base.rstrip("/").endswith(("api.openai.com", "openai.azure.com")) or "/v1" in api_base

Type guard

from litellm.exceptions import OpenAIError

def is_non_json_response_error(e: BaseException) -> bool:
    return isinstance(e, OpenAIError) and not str(getattr(e, "message", "")).strip().startswith("{")

Try / catch

from litellm.exceptions import OpenAIError

try:
    img = litellm.image_edit(model="gpt-image-1", image=image, prompt=p)
except OpenAIError as e:
    logger.error("non-JSON body (%s): %s", e.status_code, str(e.message)[:300])
    if e.status_code >= 500:
        time.sleep(2)  # retry once for transient gateway errors
        img = litellm.image_edit(model="gpt-image-1", image=image, prompt=p)
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm.image_edit() and receiving a non-JSON body: a 5xx HTML error page from a proxy or the API, an empty body from a gateway timeout, truncated multipart responses, or an OAuth/SSO login page from a misconfigured api_base.

Common situations: Custom api_base pointing at a gateway that returns HTML errors; corporate proxies intercepting requests; provider incidents returning non-JSON 500 pages; oversized image uploads rejected by intermediaries with plain-text errors.

Related errors


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