Comfy-Org/ComfyUI · error · ValueError

video length is too short

Error message

video length is too short

What it means

Inside get_sample_indices, after the duration check passes, the random-branch computes max_start = total_frames - required_origin_frames; if that is negative the clip has fewer frames than one sampling window even though the earlier duration check passed (the discrepancy comes from ceil rounding to whole source frames). It raises rather than producing negative/invalid start indices.

Source

Thrown at comfy_extras/nodes_wan.py:831

    return output_features.transpose(1, 2)  # [1, output_len, 512]


def get_sample_indices(original_fps,
                       total_frames,
                       target_fps,
                       num_sample,
                       fixed_start=None):
    required_duration = num_sample / target_fps
    required_origin_frames = int(np.ceil(required_duration * original_fps))
    if required_duration > total_frames / original_fps:
        raise ValueError("required_duration must be less than video length")

    if fixed_start is not None and fixed_start >= 0:
        start_frame = fixed_start
    else:
        max_start = total_frames - required_origin_frames
        if max_start < 0:
            raise ValueError("video length is too short")
        start_frame = np.random.randint(0, max_start + 1)
    start_time = start_frame / original_fps

    end_time = start_time + required_duration
    time_points = np.linspace(start_time, end_time, num_sample, endpoint=False)

    frame_indices = np.round(np.array(time_points) * original_fps).astype(int)
    frame_indices = np.clip(frame_indices, 0, total_frames - 1)
    return frame_indices


def get_audio_embed_bucket_fps(audio_embed, fps=16, batch_frames=81, m=0, video_rate=30):
    num_layers, audio_frame_num, audio_dim = audio_embed.shape

    if num_layers > 1:
        return_all_layers = True
    else:
        return_all_layers = False

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Skip clips whose total_frames < ceil((num_sample / target_fps) * original_fps)
  2. Use a slightly larger num_sample-buffered filter margin when curating short clips
  3. Pass fixed_start=0 for borderline clips to bypass the random-start branch

Example fix

# before
idx = get_sample_indices(30, total_frames, 16, 81)

# after: pre-filter with the same rounding
import numpy as np
need = int(np.ceil((num_sample / target_fps) * original_fps))
if total_frames < need:
    continue
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
need = int(np.ceil((num_sample / target_fps) * original_fps))
if total_frames < need:
    skip = True  # mirrors the exact rounding the function uses

Prevention

When it happens

Trigger: Edge case where required_duration <= clip duration but ceil(required_duration * original_fps) > total_frames — e.g. fractional-frame rounding with a clip exactly at or a hair under the window size; happens only in the random-start branch (fixed_start >= 0 bypasses it).

Common situations: Datasets of very short clips near the minimum length; fps combinations that make required_origin_frames round up past total_frames; boundary videos that pass one check and fail the other.

Related errors


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