{"record":{"id":"27753b211e7e44d6","repo":"huggingface/transformers","slug":"invalid-input-type-must-be-a-single-audio-or-a-li","errorCode":null,"errorMessage":"Invalid input type. Must be a single audio or a list of audio","messagePattern":"Invalid input type\\. Must be a single audio or a list of audio","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/audio_utils.py","lineNumber":421,"sourceCode":"    audio: list[AudioInput] | AudioInput,\n) -> AudioInput:\n    \"\"\"\n    Ensure that the output is a list of audio.\n    Args:\n        audio (`Union[list[AudioInput], AudioInput]`):\n            The input audio.\n    Returns:\n        list: A list of audio.\n    \"\"\"\n    # If it's a list of audios, it's already in the right format\n    if isinstance(audio, (list, tuple)) and is_valid_list_of_audio(audio):\n        return audio\n\n    # If it's a single audio, convert it to a list of\n    if is_valid_audio(audio):\n        return [audio]\n\n    raise ValueError(\"Invalid input type. Must be a single audio or a list of audio\")\n\n\ndef make_list_of_audio_chat_template(\n    audio: list[AudioInput] | AudioInput | str | list[str],\n) -> AudioInput:\n    \"\"\"\n    Ensure that the output is a list of audio. Unlike `make_list_of_audio`, this function also accepts a URL string or\n    local path, as accepted by chat templates.\n\n    Args:\n        audio (`Union[list[AudioInput], AudioInput]`):\n            The input audio. Can be a URL string, local path, numpy/torch array,  or a list of these.\n    Returns:\n        list: A list of audio.\n    \"\"\"\n\n    # Handle string inputs\n    if isinstance(audio, str):","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/audio_utils.py#L403-L439","documentation":"Thrown by `make_list_of_audio` in transformers' audio_utils when the `audio` argument is neither a single valid audio object (numpy array, torch tensor, or list/tuple of floats) nor a non-empty list/tuple whose every element is valid audio. The function normalizes user input into a list of audio before preprocessing, so any other type is rejected early. Valid audio is defined by `is_valid_audio`: np.ndarray, torch.Tensor, or a list/tuple whose first element is a float.","triggerScenarios":"Calling `make_list_of_audio(...)` (directly, or indirectly through an audio processor/preprocessor that accepts audio input) with: a plain Python string URL/path, a dict, None, an empty list, a list mixing strings and arrays, a list of lists of ints, or a PIL/soundfile object.","commonSituations":"Passing a URL or file path string to a processor feature extractor that expects raw arrays (the chat-template variant `make_list_of_audio_chat_template` accepts strings, this one does not); building chat messages with nested audio; accidentally passing a batched 2-D array of lists; migrating code that previously used strings.","solutions":["Pass a numpy array, torch tensor, or a list of floats (raw samples) instead of a path/URL string","If you have a file path or URL, load it first (e.g. with librosa.load or soundfile.read) and pass the resulting array","If you are building chat-template style input with paths/URLs, use `make_list_of_audio_chat_template` which accepts strings","Ensure the list is non-empty and every element is itself a valid audio array (no mixed types)","Wrap the call in try/except ValueError if audio comes from untrusted user input"],"exampleFix":"// before\naudio = \"sample.wav\"\naudios = make_list_of_audio(audio)  # ValueError\n\n// after\nimport soundfile as sf\naudio, sr = sf.read(\"sample.wav\")\naudios = make_list_of_audio(audio)  # -> [np.ndarray]","handlingStrategy":"type-guard","validationCode":"import numpy as np\nimport torch\n\ndef is_valid_audio(a):\n    return isinstance(a, (np.ndarray, torch.Tensor)) or (isinstance(a, (list, tuple)) and len(a) > 0 and isinstance(a[0], float))\n\ndef valid_audio_or_list(audio):\n    if is_valid_audio(audio):\n        return [audio]\n    if isinstance(audio, (list, tuple)) and audio and all(is_valid_audio(a) for a in audio):\n        return list(audio)\n    raise TypeError(\"Pass a numpy/torch array or a non-empty list of them (not a path/URL string)\")","typeGuard":"def is_audio_input_ok(audio) -> bool:\n    import numpy as np, torch\n    ok = lambda a: isinstance(a, (np.ndarray, torch.Tensor)) or (isinstance(a, (list, tuple)) and a and isinstance(a[0], float))\n    return ok(audio) or (isinstance(audio, (list, tuple)) and bool(audio) and all(ok(a) for a in audio))","tryCatchPattern":"try:\n    audios = make_list_of_audio(audio)\nexcept ValueError as e:\n    if \"Invalid input type\" in str(e):\n        raise TypeError(f\"audio must be np.ndarray/torch.Tensor or a list of them, got {type(audio)!r}\") from e\n    raise","preventionTips":["Load files/URLs to arrays before calling processors that expect raw samples","For chat-template inputs with paths/URLs use make_list_of_audio_chat_template","Never pass mixed lists (strings + arrays); normalize input upstream"],"tags":["audio","input-validation","type-error"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}