BerriAI/litellm · error · ValueError
Unsupported image type for Vertex AI Imagen image edit. Got
Error message
Unsupported image type for Vertex AI Imagen image edit. Got type={type(image)} What it means
This is the catch-all at the end of Imagen edit's _read_all_bytes: the value matched none of the accepted shapes (list/tuple, dict with data/bytes/content/path, bytes, bytearray, BytesIO, BufferedReader/BufferedRandom, str, Path) and has no .read() method. Anything else — ints, PIL Image objects, numpy arrays, torch tensors — lands here with its type printed in the message.
Source
Thrown at litellm/llms/vertex_ai/image_edit/vertex_imagen_transformation.py:350
if stream_pos is not None:
image.seek(stream_pos)
return data
if isinstance(image, str):
raise ValueError(
"Unsupported image input: plain string values are not accepted for "
"Vertex AI Imagen image edit. Provide image bytes or a file-like object."
)
if isinstance(image, Path):
raise ValueError(
"Unsupported image input: filesystem paths are not accepted for "
"Vertex AI Imagen image edit. Provide image bytes or a file-like object."
)
if hasattr(image, "read"):
data = image.read()
if isinstance(data, str):
data = data.encode("utf-8")
return data
raise ValueError(f"Unsupported image type for Vertex AI Imagen image edit. Got type={type(image)}")
View on GitHub (pinned to 77b7c6c40c)
Solutions
- PIL: buf=io.BytesIO(); img.save(buf, format='PNG'); image=buf.getvalue()
- numpy/cv2: image=cv2.imencode('.png', arr)[1].tobytes()
- Unwrap custom wrappers to raw bytes before the call
- Check the Got type=... portion of the message to find which object leaked through
Example fix
# before
from PIL import Image
resp = litellm.image_edit(
model='vertex_ai/imagen-3.0-capability-001',
prompt='edit',
image=Image.open('cat.png'), # PIL object -> raises
)
# after
from PIL import Image
import io
buf = io.BytesIO()
Image.open('cat.png').save(buf, format='PNG')
resp = litellm.image_edit(
model='vertex_ai/imagen-3.0-capability-001',
prompt='edit',
image=buf.getvalue(),
) Defensive patterns
Strategy: type-guard
Validate before calling
import io
def to_bytes(img) -> bytes:
if isinstance(img, bytes):
return img
if hasattr(img, 'read'): # file-like
return img.read()
if hasattr(img, 'save'): # PIL
buf = io.BytesIO(); img.save(buf, format='PNG'); return buf.getvalue()
if hasattr(img, 'tobytes'): # numpy
return img.tobytes()
raise TypeError(f'cannot convert {type(img)} to image bytes')
image = to_bytes(image) Type guard
def is_supported_image_value(img) -> bool:
return (
isinstance(img, (bytes, bytearray, list, tuple, dict))
or hasattr(img, 'read')
) Try / catch
try:
resp = litellm.image_edit(model='vertex_ai/imagen-...', prompt=p, image=image)
except ValueError as e:
if 'Unsupported image type' in str(e) and 'Got type=' in str(e):
image = to_bytes(image) # your PIL/numpy converter
resp = litellm.image_edit(model='vertex_ai/imagen-...', prompt=p, image=image)
else:
raise Prevention
- Convert PIL/numpy/torch images to PNG bytes before calling litellm
- Centralize conversion in one to_bytes() helper used by every upload path
- Check the 'Got type=' suffix in the message to identify which unexpected object leaked through
When it happens
Trigger: image=Image.open('cat.png') (PIL.Image.Image — no .read); image=np.ndarray from cv2/numpy pipelines; image=123 from a bad variable; a dataclass wrapping bytes without a read method.
Common situations: Computer-vision pipelines that keep images as numpy arrays or PIL objects; serialization boundaries passing through objects that lost their bytes; wrong variable passed after refactoring.
Related errors
- Unsupported image type for Vertex AI Imagen image edit.
- Unsupported image input: plain string values are not accepte
- Unsupported image input: filesystem paths are not accepted f
- Unsupported image type: {type(image)}. Expected bytes, str (
- Unsupported image type for Vertex AI Gemini image edit.
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/16f1308fb1fb0236.
Report an issue: GitHub.