Lightning-AI/pytorch-lightning · error · TypeError

Expected a list as "audios", found {type(audios)}

Error message

Expected a list as "audios", found {type(audios)}

What it means

WandbLogger.log_audio requires audios to be a Python list (of file paths or data) so each entry can be wrapped into wandb.Audio with per-item kwargs. Passing a tensor, numpy array, or other non-list raises TypeError.

Source

Thrown at src/lightning/pytorch/loggers/wandb.py:518

        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 logged
            step: The step number to be used for logging the audio files
            \**kwargs: Optional kwargs are lists passed to each ``Wandb.Audio`` instance (ex: caption, sample_rate).

        Optional kwargs are lists passed to each audio (ex: caption, sample_rate).

        """
        if not isinstance(audios, list):
            raise TypeError(f'Expected a list as "audios", found {type(audios)}')
        n = len(audios)
        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.Audio(audio, **kwarg) for audio, kwarg in zip(audios, kwarg_list)]}
        self.log_metrics(metrics, step)  # type: ignore[arg-type]

    @rank_zero_only
    def log_video(self, key: str, videos: list[Any], step: Optional[int] = None, **kwargs: Any) -> None:
        """Log videos (numpy arrays, or file paths).

        Args:
            key: The key to be used for logging the video files
            videos: The list of video file paths, or numpy arrays to be logged

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Convert to a list: list(array) / [wav for wav in tensor.cpu().numpy()]
  2. Pass file paths as a list of strings

Example fix

# before
logger.log_audio(batch_wav_tensor, sample_rate=[16000])
# after
logger.log_audio(list(batch_wav_tensor), sample_rate=[16000] * len(batch_wav_tensor))
Defensive patterns

Strategy: type-guard

Validate before calling

audios = list(audios) if not isinstance(audios, list) else audios

Type guard

def is_audio_list(x) -> bool:
    return isinstance(x, list)

Prevention

When it happens

Trigger: logger.log_audio(numpy_waveform_array, sample_rate=...) or passing a torch tensor of shape (N, samples) directly.

Common situations: Feeding a batched audio tensor straight from the training loop instead of splitting into a list of per-sample waveforms.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/e73b8a8ebc62cbdb. Report an issue: GitHub.