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

  1. PIL: buf=io.BytesIO(); img.save(buf, format='PNG'); image=buf.getvalue()
  2. numpy/cv2: image=cv2.imencode('.png', arr)[1].tobytes()
  3. Unwrap custom wrappers to raw bytes before the call
  4. 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

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


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