BerriAI/litellm · error · OpenAIError
{error_text}
Error message
{error_text} What it means
litellm's image variations handler wraps any exception raised during the synchronous image-variation request (dall-e-2 /images/variations style calls) into an OpenAIError, extracting status_code (default 500), message text, and headers from the original exception. It is the single failure boundary for the whole non-streaming variation call - covering request build, HTTP send, and upstream API errors.
Source
Thrown at litellm/llms/openai/image_variations/handler.py:110
status_code=200,
request=httpx.Request(method="GET", url="https://litellm.ai"), # mock request object
),
logging_obj=logging_obj,
request_data=data,
image=image,
optional_params=optional_params,
litellm_params=litellm_params,
encoding=None,
api_key=api_key,
)
except Exception as e:
status_code: Final = getattr(e, "status_code", 500)
error_headers = getattr(e, "headers", None)
error_text: Final = getattr(e, "text", str(e))
error_response: Final = getattr(e, "response", None)
if error_headers is None and error_response:
error_headers = getattr(error_response, "headers", None)
raise OpenAIError(status_code=status_code, message=error_text, headers=error_headers)
def image_variations(
self,
model_response: ImageResponse,
api_key: str,
api_base: str,
model: str | None,
image: FileTypes,
timeout: float | None,
custom_llm_provider: str,
logging_obj: LiteLLMLoggingObj,
optional_params: dict,
litellm_params: dict,
print_verbose: Callable | None = None,
logger_fn=None,
client=None,
organization: str | None = None,
headers: dict | None = None,View on GitHub (pinned to 77b7c6c40c)
Solutions
- Check OpenAIError.status_code: 401 = fix api_key, 429 = quota/rate limit, 400 = invalid image/params, 5xx = retry later
- Verify the input image meets requirements (PNG, size limits) for the variations endpoint
- Confirm api_base targets an endpoint that actually implements /images/variations if using a proxy/custom base
- Retry with backoff on 429/5xx; the call is idempotent for variations
Example fix
# before
resp = litellm.image_variations(image=open("cat.png","rb"), model="dall-e-2")
# OpenAIError with masked cause
# after
from litellm.exceptions import OpenAIError
try:
resp = litellm.image_variations(image=open("cat.png","rb"), model="dall-e-2")
except OpenAIError as e:
if getattr(e, "status_code", 500) == 401:
raise RuntimeError("bad OPENAI_API_KEY") from e
raise Defensive patterns
Strategy: try-catch
Validate before calling
import os
from pathlib import Path
# pre-flight checks for the variations call
def can_run_variation(image_path: str) -> bool:
p = Path(image_path)
if not p.exists() or p.stat().st_size == 0:
return False
with p.open("rb") as f:
magic = f.read(8)
return magic.startswith(b"\x89PNG\r\n\x1a\n")
assert can_run_variation("cat.png"), "need a non-empty PNG"
assert os.getenv("OPENAI_API_KEY"), "need credentials" Try / catch
from litellm.exceptions import OpenAIError
try:
resp = litellm.image_variations(image=open("cat.png", "rb"), model="dall-e-2")
except OpenAIError as e:
code = getattr(e, "status_code", 500)
if code in (429, 500, 502, 503):
time.sleep(2) # transient - retry
resp = litellm.image_variations(image=open("cat.png", "rb"), model="dall-e-2")
elif code == 401:
raise RuntimeError("invalid OPENAI_API_KEY") from e
else:
raise Prevention
- Branch on OpenAIError.status_code rather than message text - the message is the forwarded upstream body
- Validate the source image (PNG magic bytes, size, readability) before the call
- Only dall-e-2 supports variations - check the model before invoking image_variations
- Retry only 429/5xx; 4xx means your request/credentials are wrong and retries waste quota
When it happens
Trigger: Calling litellm.image_variations() when anything fails: invalid/expired API key (401), insufficient quota (429/402), invalid image payload, upstream 5xx, network timeouts, or a bad custom api_base. The original error's status and text are re-raised inside OpenAIError.
Common situations: Using dall-e-2 variation calls with rotated keys or exhausted credits; passing non-PNG/oversized source images; custom OpenAI-compatible endpoints that do not implement /images/variations; transient network failures surfacing with status 500 because the wrapped exception lacked a status_code.
Related errors
- error_message
- {raw_response.text}
- image variation provider not found: {custom_llm_provider}.
- data field is required, for openai image variations. Got={da
- Invalid value passed in for aget_assistants. Only bool or No
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/17dcf76bf8f62b9b.
Report an issue: GitHub.