{"record":{"id":"c76e67fa862929dd","repo":"unslothai/unsloth","slug":"that-reference-file-carries-no-audio-track","errorCode":null,"errorMessage":"That reference file carries no audio track.","messagePattern":"That reference file carries no audio track\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/video_minimax_h3.py","lineNumber":444,"sourceCode":"    frames = frames[: int(round(duration * H3_FPS))]\n\n    waveform, sample_rate = (None, None)\n    with av.open(io.BytesIO(blob)) as container:\n        if container.streams.audio:\n            waveform, sample_rate = _decode_audio_stream(container, np)\n    return frames, waveform, sample_rate\n\n\ndef decode_h3_reference_audio(blob: bytes) -> tuple[Any, int]:\n    \"\"\"Decode one uploaded audio file to a float32 ``(samples, channels)`` waveform + its rate.\"\"\"\n    import io\n\n    import av\n    import numpy as np\n\n    with av.open(io.BytesIO(blob)) as container:\n        if not container.streams.audio:\n            raise ValueError(\"That reference file carries no audio track.\")\n        waveform, sample_rate = _decode_audio_stream(container, np)\n    if waveform is None:\n        raise ValueError(\"That reference audio decoded to no samples.\")\n    return waveform, sample_rate\n\n\ndef _decode_audio_stream(container: Any, np: Any) -> tuple[Optional[Any], Optional[int]]:\n    \"\"\"The container's first audio stream as float32 ``(samples, channels)`` at its own rate.\n\n    Bounded while decoding, for the reason the video path above is: the encoded size says almost\n    nothing about the decoded size. A 32 MiB request-limit MP3 is over half an hour of audio, which\n    expands to ~1.9 GB of float32 here and doubles again in ``np.concatenate``, and three\n    references are accepted per request. H3's reference window is\n    ``H3_REF_VIDEO_MAX_SECONDS`` anyway, so anything past it is unusable rather than merely large:\n    refuse it with the same message the video guard uses instead of decoding it first.\"\"\"\n    import av\n\n    stream = container.streams.audio[0]","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/video_minimax_h3.py#L426-L462","documentation":"decode_h3_reference_audio opens an uploaded audio reference with PyAV and raises ValueError when container.streams.audio is empty — the uploaded file has no audio track. Structural first check, before any decode/resample work, mirroring the video path's no-video-track guard.","triggerScenarios":"Uploading a video file to the reference-audio field when it has no audio track (silent video); uploading an image or document; uploading a MIDI or other non-audio-container file.","commonSituations":"Users assuming any video upload carries sound (screen recordings often do not); field mix-ups between the audio and video reference uploaders; muted exports.","solutions":["Upload a real audio file (wav/mp3/m4a/flac) to the audio-reference field.","If using a video as the audio source, confirm it has an audio track first (ffprobe).","Validate streams client-side before submitting."],"exampleFix":"# before: silent video uploaded as audio reference -> ValueError\nupload_audio_reference(blob=silent_video_bytes)\n\n# after\nimport av, io\nwith av.open(io.BytesIO(blob)) as c:\n    if not c.streams.audio:\n        raise ValueError(\"file carries no audio; pick a real audio track\")","handlingStrategy":"validation","validationCode":"import av, io\n\ndef has_audio_track(blob: bytes) -> bool:\n    with av.open(io.BytesIO(blob)) as c:\n        return bool(c.streams.audio)","typeGuard":null,"tryCatchPattern":"try:\n    wf, sr = decode_h3_reference_audio(blob)\nexcept ValueError as e:\n    if \"no audio track\" in str(e):\n        return HTTPException(400, \"upload an audio file for the audio reference\")\n    raise","preventionTips":["Accept audio/* only in the audio-reference field.","Silent screen recordings are the classic trap — check streams.audio first.","Probe uploads server-side before queuing generation."],"tags":["audio","minimax-h3","upload","validation","pyav"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}