Lightning-AI/pytorch-lightning · error · TypeError
Expected a list as "images", found {type(images)}
Error message
Expected a list as "images", found {type(images)} What it means
WandbLogger.log_image requires the images argument to be a Python list (each element is then wrapped into wandb.Image with per-item kwargs). Passing a tensor, numpy array, tuple, or generator triggers this TypeError before anything is logged.
Source
Thrown at src/lightning/pytorch/loggers/wandb.py:492
step: Optional[int] = None,
) -> None:
"""Log text as a Table.
Can be defined either with `columns` and `data` or with `dataframe`.
"""
self.log_table(key, columns, data, dataframe, step)
@rank_zero_only
def log_image(self, key: str, images: list[Any], step: Optional[int] = None, **kwargs: Any) -> None:
"""Log images (tensors, numpy arrays, PIL Images or file paths).
Optional kwargs are lists passed to each image (ex: caption, masks, boxes).
"""
if not isinstance(images, list):
raise TypeError(f'Expected a list as "images", found {type(images)}')
n = len(images)
for k, v in kwargs.items():
if len(v) != n:
raise ValueError(f"Expected {n} items but only found {len(v)} for {k}")
kwarg_list = [{k: kwargs[k][i] for k in kwargs} for i in range(n)]
import wandb
metrics = {key: [wandb.Image(img, **kwarg) for img, kwarg in zip(images, kwarg_list)]}
self.log_metrics(metrics, step) # type: ignore[arg-type]
@rank_zero_only
def log_audio(self, key: str, audios: list[Any], step: Optional[int] = None, **kwargs: Any) -> None:
r"""Log audios (numpy arrays, or file paths).
Args:
key: The key to be used for logging the audio files
audios: The list of audio file paths, or numpy arrays to be loggedView on GitHub (pinned to 9fed5c27d2)
Solutions
- Wrap the batch into a list: list(tensor) or images.tolist()/images.cpu() split per sample
- Convert numpy arrays: [np_img for np_img in arr]
- Unpack tuples/generators: list(images)
Example fix
# before logger.log_image(images=batch_tensor, caption=["a", "b"]) # after logger.log_image(images=list(batch_tensor), caption=["a", "b"])
Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(images, list), "images must be a list"
Type guard
def is_image_list(x) -> bool:
return isinstance(x, list) and len(x) > 0 and all(isinstance(i, (str,)) or hasattr(i, "__array__") or torch.is_tensor(i) for i in x) Prevention
- Always convert batches to per-sample lists before wandb media calls
- Write a small wrapper that normalizes inputs to log_image/log_audio/log_video
When it happens
Trigger: logger.log_image(tensor_batch, ...) or logger.log_image(np.array([...]), ...) instead of logger.log_image([t1, t2], ...); also passing a tuple.
Common situations: Passing a raw (C,H,W)/(B,C,H,W) torch tensor directly from a training step instead of converting to a list of per-sample tensors/images.
Related errors
- Expected {n} items but only found {len(v)} for {k}
- Expected a list as "audios", found {type(audios)}
- Expected a list as "videos", found {type(videos)}
- `name` must be a str, found {name}
- Expected `torch.nn.Module` or `torch.optim.Optimizer`, got:
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/45d1523372e7f799.
Report an issue: GitHub.