Comfy-Org/ComfyUI · error · ValueError

MiniMax H3 reference videos need at least 5 frames (~0.2s at

Error message

MiniMax H3 reference videos need at least 5 frames (~0.2s at 24 fps)

What it means

MiniMaxH3ReferenceToVideo requires each reference video to keep at least 5 frames after resizing/canvas adaptation and trimming to frame_count, because H3 video tokenization needs clips whose length is 5 mod 17 (5 being the minimum). Fewer than 5 frames cannot form a single valid video token group (~0.2s at 24 fps).

Source

Thrown at comfy_extras/nodes_minimax_h3.py:325

            ref_blocks.append({"kind": "image", "latent_h": th // 16, "latent_w": tw // 16, "latent": z})

        ref_video_audios = ref_video_audios or {}
        for name, video_frames in (ref_videos or {}).items():
            if video_frames is None:
                continue
            # index-paired soundtrack: ref_video_audio_N belongs to ref_video_N
            soundtrack = ref_video_audios.get("ref_video_audio_" + name.rsplit("_", 1)[-1])
            vh, vw = video_frames.shape[1], video_frames.shape[2]
            cw, ch = adapt_canvas(vw, vh)
            if vw * vh < cw * ch:
                cw = max(CANVAS_MULTIPLE, round(vw / CANVAS_MULTIPLE) * CANVAS_MULTIPLE)
                ch = max(CANVAS_MULTIPLE, round(vh / CANVAS_MULTIPLE) * CANVAS_MULTIPLE)
            frames = _resize(video_frames, cw, ch, "disabled")
            if frames.shape[0] > frame_count:
                frames = frames[:frame_count]
            n = frames.shape[0]
            if n < 5:
                raise ValueError("MiniMax H3 reference videos need at least 5 frames (~0.2s at 24 fps)")
            while n % 17 != 5:
                n -= 1
            frames = frames[:n]
            z = vae.encode(frames)
            audio_latent, ref_audio_t = (None, 0)
            if soundtrack is not None:
                audio_latent, ref_audio_t = _encode_ref_audio(audio_vae, soundtrack)
                # the soundtrack gets its own <Audio j> label, emitted before <Video k>
                ref_items.append({"type": "audio"})
            # Qwen sees the video at 2 fps with timestamps
            sample_idx = list(range(0, frames.shape[0], FPS // 2))
            qwen_frames = frames[sample_idx]
            ref_items.append({"type": "video", "data": qwen_frames,
                              "timestamps": [i / 2.0 for i in range(len(sample_idx))]})
            ref_blocks.append({"kind": "video_audio" if ref_audio_t else "video",
                               "latent_t": z.shape[2], "latent_h": ch // 16, "latent_w": cw // 16,
                               "ref_audio_t": ref_audio_t, "latent": z, "audio_latent": audio_latent})

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Supply a reference video with at least 5 frames (ideally 5, 22, 39... frames for exact token fit).
  2. For a single reference image, use the reference-image input path instead of the video input.
  3. Raise frame_count so the trim step cannot cut the ref below 5 frames.
Defensive patterns

Strategy: validation

Validate before calling

n = min(video_frames.shape[0], frame_count)
if n < 5:
    raise UserFacingError('reference video needs >= 5 frames')

Prevention

When it happens

Trigger: Passing a ref video of 1-4 frames, or one trimmed by 'if frames.shape[0] > frame_count: frames = frames[:frame_count]' down to under 5 frames because frame_count is small.

Common situations: Using a single image or a 2-3 frame GIF as a 'reference video'; frame_count limits derived from a very short target latent truncating the reference; ffmpeg export producing tiny clips.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/e122982ba17351fc. Report an issue: GitHub.