Comfy-Org/ComfyUI · error · ValueError

frame_idx {} is outside the video's {} frames

Error message

frame_idx {} is outside the video's {} frames

What it means

For a single-frame guide (image batch < 5 frames), the requested frame_idx must resolve to a valid frame index within the video: 0 <= resolved < frame_count. Negative indices are resolved relative to the end (frame_count + frame_idx), and the error reports the raw frame_idx against the total frame count.

Source

Thrown at comfy_extras/nodes_minimax_h3.py:212

        height = video.shape[3] * 16
        width = video.shape[4] * 16
        frame_count = sum(FRAME_PER_TOKEN[k % 5] for k in range(video.shape[2]))

        guide_frames = 1
        if image is not None:
            if vae is None:
                raise ValueError("anchoring guide frames needs the vae input")
            guide_frames = image.shape[0]
            if guide_frames < 5:
                guide_frames = 1
            else:
                while guide_frames % 17 != 5:
                    guide_frames -= 1

        resolved_frame_index = frame_idx if frame_idx >= 0 else frame_count + frame_idx
        if resolved_frame_index < 0 or resolved_frame_index + guide_frames > frame_count:
            if guide_frames == 1:
                raise ValueError("frame_idx {} is outside the video's {} frames".format(frame_idx, frame_count))
            raise ValueError("a {} frame guide clip at frame_idx {} does not fit in the video's {} frames".format(
                guide_frames, frame_idx, frame_count))

        keyframe = {"resolved_frame_index": resolved_frame_index}
        if image is not None:
            frames = _resize(image[:guide_frames], width, height, "center")
            keyframe["latent"] = vae.encode(frames)

        if audio is not None:
            if audio_vae is None:
                raise ValueError("anchoring guide audio needs the audio_vae input")
            audio_latent, audio_rt = _encode_ref_audio(audio_vae, audio)
            # the streams share one time axis: FRAME_RESCALE per pixel frame, 1.0 per audio latent frame
            max_rt = math.floor(samples.tensors[1].shape[-1] - FRAME_RESCALE * resolved_frame_index)
            if max_rt < 1:
                raise ValueError("frame_idx {} is past the end of the video's audio track".format(frame_idx))
            if audio_rt > max_rt:
                audio_latent = audio_latent[..., :max_rt].clone()

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Set frame_idx within [0, frame_count-1]; remember frame_count is the token-derived video frame count, not the latent length.
  2. For negative values use -1 (last frame) style indexing and keep |frame_idx| < frame_count.
  3. Generate a longer latent upstream if the anchor must sit late in the video.
Defensive patterns

Strategy: validation

Validate before calling

frame_count = sum(FRAME_PER_TOKEN[k % 5] for k in range(video.shape[2]))
resolved = frame_idx if frame_idx >= 0 else frame_count + frame_idx
assert 0 <= resolved < frame_count, f'frame_idx {frame_idx} out of {frame_count} frames'

Prevention

When it happens

Trigger: frame_idx >= frame_count, or a negative frame_idx whose magnitude exceeds frame_count (resolved_frame_index < 0); frame_count is derived from the video latent tokens via the FRAME_PER_TOKEN pattern (variable frames per token, 4+1 cyclic).

Common situations: Assuming a 25 fps or per-pixel-frame count when H3 packs frames into tokens with a 4-then-1 pattern; hardcoding frame_idx=81 for a short clip; negative indexing on very short latents.

Related errors


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