{"record":{"id":"7280a255637f37d3","repo":"unslothai/unsloth","slug":"that-reference-file-carries-no-video-track","errorCode":null,"errorMessage":"That reference file carries no video track.","messagePattern":"That reference file carries no video track\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/inference/video_minimax_h3.py","lineNumber":385,"sourceCode":"\n\ndef decode_h3_reference_video(blob: bytes) -> tuple[list, Optional[Any], Optional[int]]:\n    \"\"\"Decode one uploaded video to 24 fps frames plus its soundtrack, if it carries one.\n\n    Returns ``(frames, waveform, sample_rate)``. The frames land on MiniMax-H3's own 24 fps by\n    whole-frame drop and duplicate -- the selection ffmpeg's fps filter made in the reference\n    implementation, and the one the Diffusers blocks make from a declared rate -- so both\n    engines receive a stream that is already on the model's clock. The waveform is float32\n    ``(samples, channels)`` at the container's own rate; both engines resample it themselves.\n    \"\"\"\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.video:\n            raise ValueError(\"That reference file carries no video track.\")\n        stream = container.streams.video[0]\n        source_fps = float(stream.average_rate or stream.guessed_rate or H3_FPS)\n        if source_fps <= 0:\n            source_fps = float(H3_FPS)\n        # Select, resample, and resize incrementally to bound memory for 4K inputs.\n        from PIL import Image\n\n        frames = []\n        decoded_count = 0\n        next_target = 0\n        fitted_size = None\n        max_source_frames = math.floor(H3_REF_VIDEO_MAX_SECONDS * source_fps + 1e-6)\n        for source_index, frame in enumerate(container.decode(video = 0)):\n            decoded_count = source_index + 1\n            if decoded_count > max_source_frames:\n                raise ValueError(\n                    f\"MiniMax-H3 reference videos run {H3_REF_VIDEO_MIN_SECONDS:g} to \"\n                    f\"{H3_REF_VIDEO_MAX_SECONDS:g} seconds; this one is longer than \"","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/video_minimax_h3.py#L367-L403","documentation":"decode of an uploaded MiniMax-H3 reference video opens the blob with PyAV and raises ValueError when container.streams.video is empty — the uploaded file carries no video track. This is the earliest possible structural check, before any fps/frame work, so wrong-file uploads fail fast with a clear message.","triggerScenarios":"Uploading an audio file (MP3/WAV/M4A) to the reference-video field; uploading a container whose video track is unparseable; uploading an image where a video was required.","commonSituations":"Frontend file pickers accepting audio/* for the video reference slot; users uploading a soundtrack where a motion reference was expected; extension-mislabeled files.","solutions":["Upload an actual video file (mp4/webm/mov) to the reference-video field.","Validate client-side with ffprobe or an av stream check before submitting.","Use the dedicated reference-audio upload path for audio files."],"exampleFix":"# before\nupload_reference(blob=music_mp3)  # -> ValueError: no video track\n\n# after: check before upload\nimport av, io\nwith av.open(io.BytesIO(blob)) as c:\n    if not c.streams.video:\n        raise ValueError(\"expected a video file\")","handlingStrategy":"validation","validationCode":"import av, io\n\ndef has_video_track(blob: bytes) -> bool:\n    with av.open(io.BytesIO(blob)) as c:\n        return bool(c.streams.video)","typeGuard":null,"tryCatchPattern":"try:\n    frames, wf, sr = decode_h3_reference_video(blob)\nexcept ValueError as e:\n    if \"no video track\" in str(e):\n        return HTTPException(400, \"upload a video file for the video reference\")\n    raise","preventionTips":["Restrict the video-reference upload field to video/* MIME types.","Probe container streams server-side before accepting the upload.","Keep audio and video reference fields visually distinct in the UI."],"tags":["video","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"}