Comfy-Org/ComfyUI · error · ValueError

SeedVR2Preprocess expected at least one frame.

Error message

SeedVR2Preprocess expected at least one frame.

What it means

Raised by cut_videos in the SeedVR2 preprocessing path when the input video tensor has zero frames along the temporal dimension (t < 1). SeedVR2 requires at least one frame to build a 4n+1 temporal layout, so an empty sequence is rejected before padding. This is a shape-contract error, not a runtime environment problem.

Source

Thrown at comfy_extras/nodes_seedvr.py:78


def div_pad(image, factor):
    height_factor, width_factor = factor
    height, width = image.shape[-2:]

    pad_height = (height_factor - (height % height_factor)) % height_factor
    pad_width = (width_factor - (width % width_factor)) % width_factor

    if pad_height == 0 and pad_width == 0:
        return image

    padding = (0, pad_width, 0, pad_height)
    return torch.nn.functional.pad(image, padding, mode='constant', value=0.0)

def cut_videos(videos):
    t = videos.size(1)
    if t < 1:
        raise ValueError("SeedVR2Preprocess expected at least one frame.")
    if t == 1:
        return videos
    if t <= 4:
        padding = videos[:, -1:].repeat(1, 4 - t + 1, 1, 1, 1)
        return torch.cat([videos, padding], dim=1)
    if (t - 1) % 4 == 0:
        return videos
    padding = videos[:, -1:].repeat(1, 4 - ((t - 1) % 4), 1, 1, 1)
    videos = torch.cat([videos, padding], dim=1)
    if (videos.size(1) - 1) % 4 != 0:
        raise ValueError(f"SeedVR2Preprocess failed to pad video length to 4n+1; got {videos.size(1)} frames.")
    return videos

def _seedvr2_input_shorter_edge(images, node_name):
    if images.dim() == 4:
        return min(images.shape[1], images.shape[2])
    if images.dim() == 5:
        return min(images.shape[2], images.shape[3])

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Check the frame count of the tensor feeding the SeedVR2 node before it runs: images.shape[0] (for a 4-D frame stack) must be >= 1.
  2. Fix the upstream video loader / frame-selection node so it outputs at least one frame (start frame < end frame).
  3. If frames are selected dynamically, guard with: n = images.shape[0]; sel = images[max(0, min(start, n-1)):max(start+1, min(end, n))] so at least one frame survives.

Example fix

# before
frames = video[:, start:end]  # start == end -> 0 frames -> ValueError

# after
if end <= start:
    raise ValueError("frame range is empty: end must be > start")
frames = video[:, start:end]
Defensive patterns

Strategy: validation

Validate before calling

def has_frames(image):
    # 4-D (N,H,W,C) or 5-D (B,N,H,W,C) Comfy IMAGE
    return image.dim() in (4, 5) and image.shape[-4] >= 1

Type guard

def is_nonempty_video_image(t) -> bool:
    return t.dim() in (4, 5) and t.shape[-4] >= 1 and t.shape[-1] in (1, 3, 4)

Prevention

When it happens

Trigger: Passing an IMAGE tensor whose frame dimension (size(1) after the batchunsqueeze, i.e. videos.size(1) < 1) is empty. Typically an empty batch of frames from an upstream node (e.g. LoadVideo with a zero-length range, or a batch node that produced 0 frames) reaching SeedVR2Preprocess/cut_videos.

Common situations: Video loader configured with an empty frame range or start >= end; a downstream node slicing frames out of range ([10:10]) producing a 0-frame tensor; a workflow wired to an empty image list.

Related errors


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