hiyouga/LlamaFactory · error · ValueError
Expect input is a list of images, but got {type(image)}.
Error message
Expect input is a list of images, but got {type(image)}. What it means
Thrown in BasePlugin._regularize_images when an element of the `images` list cannot be coerced into a PIL Image. Supported inputs are: file path str / file-like object (opened via Image.open), raw bytes, a dict with 'bytes' or 'path' keys, or an already-loaded PIL Image. Anything else (int, None, numpy array, broken object) reaches the isinstance check and fails.
Source
Thrown at src/llamafactory/data/mm_plugin.py:272
r"""Build metadata used to expand video tokens without decoding frames."""
return None
def _regularize_images(self, images: list["ImageInput"], **kwargs) -> "RegularizedImageOutput":
r"""Regularize images to avoid error. Including reading and pre-processing."""
results = []
for image in images:
if isinstance(image, (str, BinaryIO)):
image = Image.open(image)
elif isinstance(image, bytes):
image = Image.open(BytesIO(image))
elif isinstance(image, dict):
if image["bytes"] is not None:
image = Image.open(BytesIO(image["bytes"]))
else:
image = Image.open(image["path"])
if not isinstance(image, ImageObject):
raise ValueError(f"Expect input is a list of images, but got {type(image)}.")
results.append(self._preprocess_image(image, **kwargs))
return {"images": results}
def _regularize_videos(self, videos: list["VideoInput"], **kwargs) -> "RegularizedVideoOutput":
r"""Regularizes videos to avoid error. Including reading, resizing and converting."""
results = []
durations = []
for video in videos:
frames: list[ImageObject] = []
if _check_video_is_nested_images(video):
for frame in video:
if not is_valid_image(frame) and not isinstance(frame, dict) and not os.path.exists(frame):
raise ValueError("Invalid image found in video frames.")
frames = video
durations.append(len(frames) / kwargs.get("video_fps", 2.0))
else:View on GitHub (pinned to f28afaf635)
Solutions
- Convert each image to PIL before passing: Image.fromarray(arr) for numpy, or pass file paths / {'bytes': ..., 'path': ...} dicts.
- Filter or repair rows with null/missing image values in the dataset.
- Ensure you pass a list of images, not a bare image or nested lists.
Example fix
# before images = [np_array] # numpy RGB array # after from PIL import Image images = [Image.fromarray(np_array)]
Defensive patterns
Strategy: type-guard
Validate before calling
from PIL import Image
def valid_image_inputs(images):
for im in images:
if isinstance(im, (str, bytes, dict)) or isinstance(im, Image.Image):
continue
if hasattr(im, 'read'): # file-like
continue
return False
return True Type guard
from PIL import Image
from typing import Union
ImageInputOK = Union[str, bytes, dict, Image.Image]
def is_image_input(x) -> bool:
return isinstance(x, (str, bytes, dict, Image.Image)) or hasattr(x, 'read') Try / catch
try:
mm = plugin.process_messages(messages, images, [], [], processor)
except ValueError as e:
if 'list of images' in str(e):
images = [Image.open(p) if isinstance(p, str) else p for p in images]
else:
raise Prevention
- Store images in datasets as paths or {'bytes':..., 'path':...} dicts, never raw arrays.
- Drop rows with null image fields during data prep.
When it happens
Trigger: Passing images as numpy arrays, torch tensors, None entries, or a single Image instead of a list to _regularize_images / process_messages. Also a dict without 'bytes'/'path' keys, or an object whose type is not PIL.Image.Image.
Common situations: Datasets stored as decoded numpy frames; a column that is null for some rows; iterating a column that yields scalars; HF datasets pushing an unexpected Arrow type.
Related errors
- This model does not support image input. Please check whethe
- The number of images does not match the number of {IMAGE_PLA
- The number of videos does not match the number of {VIDEO_PLA
- Please upgrade `transformers` to 4.34.0
- Unable to process key {key}
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/2fc2a842812b7e58.
Report an issue: GitHub.