huggingface/transformers · error · ValueError

Could not make a flat list of images from {images}

Error message

Could not make a flat list of images from {images}

What it means

Raised by `transformers.image_utils.make_flat_list_of_images` (default `expected_ndims=3`) when the input's structure cannot be flattened into a list of single images. The helper accepts: a list of valid images each with ndim == expected_ndims, a list of batches each with ndim == expected_ndims + 1, a single image, or a single batch tensor. Any other combination — wrong rank per element, lists of lists of lists, or a non-image type — reaches this catch-all ValueError.

Source

Thrown at src/transformers/image_utils.py:237

        isinstance(images, (list, tuple))
        and all(isinstance(images_i, (list, tuple)) for images_i in images)
        and all(is_valid_list_of_images(images_i) or not images_i for images_i in images)
    ):
        return [img for img_list in images for img in img_list]

    if isinstance(images, (list, tuple)) and is_valid_list_of_images(images):
        if is_pil_image(images[0]) or images[0].ndim == expected_ndims:
            return images
        if images[0].ndim == expected_ndims + 1:
            return [img for img_list in images for img in img_list]

    if is_valid_image(images):
        if is_pil_image(images) or images.ndim == expected_ndims:
            return [images]
        if images.ndim == expected_ndims + 1:
            return list(images)

    raise ValueError(f"Could not make a flat list of images from {images}")


def make_nested_list_of_images(
    images: list[ImageInput] | ImageInput,
    expected_ndims: int = 3,
) -> list[ImageInput]:
    """
    Ensure that the output is a nested 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 list of images or a list of 4d array of images.
    """
    # If it's a list of batches, it's already in the right format
    if (

View on GitHub (pinned to a597f97485)

Solutions

  1. Flatten your input to at most one level of nesting over single images: `[img for batch in batches for img in batch]`.
  2. Ensure every element is a valid image (PIL/np/torch) with exactly `expected_ndims` dimensions — add the channel axis back to 2D arrays.
  3. Load any path/URL strings with `load_images()` before passing them in.
  4. Set `expected_ndims` to match your data if you genuinely have a different rank (e.g. 2 for masks).

Example fix

// before
flat = make_flat_list_of_images([[[img1, img2], [img3]]])  # too deeply nested
flat = make_flat_list_of_images([np.zeros((h, w))])        # 2D element -> ValueError

// after
flat = make_flat_list_of_images([img1, img2, img3])
flat = make_flat_list_of_images([np.zeros((1, h, w))])
Defensive patterns

Strategy: validation

Validate before calling

from transformers.image_utils import is_valid_image

def flatten_images(maybe_nested, expected_ndims: int = 3):
    flat = [img for sub in maybe_nested for img in sub] if maybe_nested and isinstance(maybe_nested[0], (list, tuple)) else maybe_nested
    flat = flat if isinstance(flat, (list, tuple)) else [flat]
    assert all(is_valid_image(i) and (not hasattr(i, "ndim") or i.ndim == expected_ndims) for i in flat)
    return list(flat)

Type guard

from transformers.image_utils import is_valid_image

def is_flattenable(x, expected_ndims: int = 3) -> bool:
    if is_valid_image(x):
        return not hasattr(x, "ndim") or x.ndim in (expected_ndims, expected_ndims + 1)
    return isinstance(x, (list, tuple)) and bool(x) and all(
        is_valid_image(i) and (not hasattr(i, "ndim") or i.ndim == expected_ndims) for i in x
    )

Prevention

When it happens

Trigger: Passing a doubly-nested list [[[img, img], [img, img]]] (more than two levels); a list whose elements are 2D arrays when expected_ndims=3; a mixed list like [PIL_image, np_2d_array]; or an input like a plain string. Typically reached through `processor.preprocess()` on processors that flatten inputs.

Common situations: Batched inference code wrapping already-nested batches one more time; grayscale/mask arrays that dropped a channel axis; heterogeneous data lists where one element has a different shape than the rest.

Related errors


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