BerriAI/litellm · error · ValueError
Unsupported image type: {type(image)}. Expected bytes, str (
Error message
Unsupported image type: {type(image)}. Expected bytes, str (URL or file path), or file-like object. What it means
_read_image_bytes accepts only three shapes: bytes, URL-prefixed strings (plus one-level lists of them), and objects with a .read() method. Any other type — int, dict, None, PIL.Image, numpy array, pathlib.Path — falls to the final else and raises ValueError naming the received type. This is a client-side argument-type failure raised before any HTTP traffic.
Source
Thrown at litellm/llms/black_forest_labs/image_edit/transformation.py:226
response: Final = safe_get(litellm.module_level_client, image, timeout=60.0)
response.raise_for_status()
return response.content
else:
raise ValueError(
"Unsupported image input: plain string values that are not URLs are not accepted. "
"Provide image bytes or a file-like object."
)
elif hasattr(image, "read"):
# File-like object
pos: Final = getattr(image, "tell", lambda: 0)()
if hasattr(image, "seek"):
image.seek(0)
data: Final = image.read()
if hasattr(image, "seek"):
image.seek(pos)
return data
else:
raise ValueError(
f"Unsupported image type: {type(image)}. Expected bytes, str (URL or file path), or file-like object."
)
def transform_image_edit_request(
self,
model: str,
prompt: str | None,
image: FileTypes | None,
image_edit_optional_request_params: dict,
litellm_params: GenericLiteLLMParams,
headers: dict,
) -> tuple[dict, RequestFiles]:
"""
Transform OpenAI-style request to Black Forest Labs request format.
BFL uses JSON body with base64-encoded images, not multipart/form-data.
"""
# Read and encode imageView on GitHub (pinned to 6c2dcb801b)
Solutions
- Convert before calling: PIL -> io.BytesIO via img.save(buf, format='PNG'); numpy -> img.tobytes(); Path -> path.read_bytes().
- Always pass one of: bytes, https URL string, or an open binary file object.
- Assert the type in your own wrapper so bad values fail loudly at your boundary, not inside LiteLLM.
Example fix
# before litellm.image_edit(model=..., image=pil_img, prompt="...") # after import io buf = io.BytesIO(); pil_img.save(buf, format="PNG") litellm.image_edit(model=..., image=buf.getvalue(), prompt="...")
Defensive patterns
Strategy: type-guard
Validate before calling
import io
def coerce_image(x):
if hasattr(x, "read"): return x
if isinstance(x, bytes): return x
if isinstance(x, str) and x.startswith(("http://","https://")): return x
if x.__class__.__name__ == "PngImagePlugin" or hasattr(x, "save"):
buf = io.BytesIO(); x.save(buf, format="PNG"); return buf.getvalue()
if hasattr(x, "tobytes"): return x.tobytes()
raise TypeError(f"cannot coerce {type(x)} to BFL image") Type guard
from typing import Any
def is_bfl_supported_image(x: Any) -> bool:
return (
isinstance(x, bytes)
or (isinstance(x, str) and x.startswith(("http://", "https://")))
or hasattr(x, "read")
or (isinstance(x, list) and x and is_bfl_supported_image(x[0]))
) Try / catch
null
Prevention
- Convert PIL/numpy/Path objects to bytes in your own adapter layer, never inside the call site.
- Add unit tests asserting is_bfl_supported_image over every input path your pipeline produces.
- Document to callers that the image parameter accepts bytes/URL/file-like only.
When it happens
Trigger: Passing image as a PIL.Image.Image, numpy.ndarray, pathlib.Path, dict, or None to image_edit with a black_forest_labs model.
Common situations: Feeding the output of an upstream Python imaging pipeline (PIL/numpy) straight into image_edit; passing Path objects since they feel string-like; forgetting the image argument entirely in a wrapper function (None).
Related errors
- Max recursion depth {max_depth} reached while reading image
- Unsupported image input: plain string values that are not UR
- limit must be an integer
- api base needs to be a string. api_base={api_base}
- dynamic_api_key needs to be a string. Got type={type(dynamic
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/1c5fd484f7d46bbb.
Report an issue: GitHub.