unslothai/unsloth · error · ValueError

That reference file carries no video track.

Error message

That reference file carries no video track.

What it means

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.

Source

Thrown at studio/backend/core/inference/video_minimax_h3.py:385


def decode_h3_reference_video(blob: bytes) -> tuple[list, Optional[Any], Optional[int]]:
    """Decode one uploaded video to 24 fps frames plus its soundtrack, if it carries one.

    Returns ``(frames, waveform, sample_rate)``. The frames land on MiniMax-H3's own 24 fps by
    whole-frame drop and duplicate -- the selection ffmpeg's fps filter made in the reference
    implementation, and the one the Diffusers blocks make from a declared rate -- so both
    engines receive a stream that is already on the model's clock. The waveform is float32
    ``(samples, channels)`` at the container's own rate; both engines resample it themselves.
    """
    import io

    import av
    import numpy as np

    with av.open(io.BytesIO(blob)) as container:
        if not container.streams.video:
            raise ValueError("That reference file carries no video track.")
        stream = container.streams.video[0]
        source_fps = float(stream.average_rate or stream.guessed_rate or H3_FPS)
        if source_fps <= 0:
            source_fps = float(H3_FPS)
        # Select, resample, and resize incrementally to bound memory for 4K inputs.
        from PIL import Image

        frames = []
        decoded_count = 0
        next_target = 0
        fitted_size = None
        max_source_frames = math.floor(H3_REF_VIDEO_MAX_SECONDS * source_fps + 1e-6)
        for source_index, frame in enumerate(container.decode(video = 0)):
            decoded_count = source_index + 1
            if decoded_count > max_source_frames:
                raise ValueError(
                    f"MiniMax-H3 reference videos run {H3_REF_VIDEO_MIN_SECONDS:g} to "
                    f"{H3_REF_VIDEO_MAX_SECONDS:g} seconds; this one is longer than "

View on GitHub (pinned to 203007d190)

Solutions

  1. Upload an actual video file (mp4/webm/mov) to the reference-video field.
  2. Validate client-side with ffprobe or an av stream check before submitting.
  3. Use the dedicated reference-audio upload path for audio files.

Example fix

# before
upload_reference(blob=music_mp3)  # -> ValueError: no video track

# after: check before upload
import av, io
with av.open(io.BytesIO(blob)) as c:
    if not c.streams.video:
        raise ValueError("expected a video file")
Defensive patterns

Strategy: validation

Validate before calling

import av, io

def has_video_track(blob: bytes) -> bool:
    with av.open(io.BytesIO(blob)) as c:
        return bool(c.streams.video)

Try / catch

try:
    frames, wf, sr = decode_h3_reference_video(blob)
except ValueError as e:
    if "no video track" in str(e):
        return HTTPException(400, "upload a video file for the video reference")
    raise

Prevention

When it happens

Trigger: 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.

Common situations: Frontend file pickers accepting audio/* for the video reference slot; users uploading a soundtrack where a motion reference was expected; extension-mislabeled files.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/7280a255637f37d3. Report an issue: GitHub.