huggingface/transformers · error · ValueError

Invalid image type. Expected either PIL.Image.Image, numpy.n

Error message

Invalid image type. Expected either PIL.Image.Image, numpy.ndarray, or torch.Tensor, but got {type(images)}.

What it means

Raised by `transformers.image_utils.make_list_of_images` as its final fallthrough when the input is neither a PIL.Image.Image, a numpy.ndarray, nor a torch.Tensor (the `is_valid_image` check failed). The message names the three accepted types and the actual type received. It is an input-contract error: the helper only re-packages valid images into a list and never converts or loads anything.

Source

Thrown at src/transformers/image_utils.py:197

    # Either the input is a single image, in which case we create a list of length 1
    if is_pil_image(images):
        # PIL images are never batched
        return [images]

    if is_valid_image(images):
        if images.ndim == expected_ndims + 1:
            # Batch of images
            images = list(images)
        elif images.ndim == expected_ndims:
            # Single image
            images = [images]
        else:
            raise ValueError(
                f"Invalid image shape. Expected either {expected_ndims + 1} or {expected_ndims} dimensions, but got"
                f" {images.ndim} dimensions."
            )
        return images
    raise ValueError(
        f"Invalid image type. Expected either PIL.Image.Image, numpy.ndarray, or torch.Tensor, but got {type(images)}."
    )


def make_flat_list_of_images(
    images: list[ImageInput] | ImageInput,
    expected_ndims: int = 3,
) -> ImageInput:
    """
    Ensure that the output is a flat list of images. If the input is a single image, it is converted to a list of length 1.
    If the input is a nested list of images, it is converted to a flat list of images.
    Args:
        images (`Union[list[ImageInput], ImageInput]`):
            The input image.
        expected_ndims (`int`, *optional*, defaults to 3):
            The expected number of dimensions for a single input image.
    Returns:
        list: A list of images or a 4d array of images.

View on GitHub (pinned to a597f97485)

Solutions

  1. Load strings first: `image = load_image('path_or_url_or_base64')` produces a PIL image the helper accepts.
  2. Convert non-supported tensors: `np.array(x)` or `x.numpy()` for tf tensors.
  3. For batches, pass a list/tuple whose elements are each PIL/np/torch images, e.g. `[img1, img2]`.

Example fix

// before
inputs = processor(images="/data/cat.jpg", return_tensors="pt")  # ValueError

// after
from transformers.image_utils import load_image
inputs = processor(images=load_image("/data/cat.jpg"), return_tensors="pt")
Defensive patterns

Strategy: type-guard

Validate before calling

from transformers.image_utils import is_valid_image, is_valid_list_of_images

assert is_valid_image(images) or is_valid_list_of_images(images), (
    f"Expected PIL.Image, np.ndarray, or torch.Tensor (or list of them), got {type(images)}"
)

Type guard

from transformers.image_utils import is_valid_image

def is_acceptable_image_input(x) -> bool:
    return is_valid_image(x) or (isinstance(x, (list, tuple)) and bool(x) and all(is_valid_image(i) for i in x))

Prevention

When it happens

Trigger: Calling `make_list_of_images()` (or an image processor preprocess path that uses it) with a TensorFlow tensor, a plain Python list of numbers (not a list of images), a string path, bytes, or None.

Common situations: Passing a raw file path or URL string to `preprocess` instead of loading it first with `load_image`/`load_images`; mixing TensorFlow/Keras pipelines with transformers image processors; passing None from a failed upstream load.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/6872017196fb51cb. Report an issue: GitHub.