Comfy-Org/ComfyUI · error · ValueError

Video too short: need at least 16 frames for Moonvalley

Error message

Video too short: need at least 16 frames for Moonvalley

What it means

The Moonvalley trim helper rounds the target frame count down to the nearest multiple of 16 (a hard requirement of that model's video encoder). estimated_frames = int(duration_sec * fps); target_frames = (estimated_frames // 16) * 16. When the requested duration at the source fps yields fewer than 16 frames, target_frames becomes 0 and the helper refuses to encode.

Source

Thrown at comfy_api_nodes/util/conversions.py:360

                video_stream = output_container.add_stream("h264", rate=stream.average_rate)
                video_stream.width = stream.width
                video_stream.height = stream.height
                video_stream.pix_fmt = "yuv420p"
                logging.info("Added video stream: %sx%s @ %sfps", stream.width, stream.height, stream.average_rate)
            elif isinstance(stream, av.AudioStream):
                # Create output audio stream with same parameters
                audio_stream = output_container.add_stream("aac", rate=stream.sample_rate)
                audio_stream.sample_rate = stream.sample_rate
                audio_stream.layout = stream.layout
                logging.info("Added audio stream: %sHz, %s channels", stream.sample_rate, stream.channels)

        # Calculate target frame count that's divisible by 16
        fps = input_container.streams.video[0].average_rate
        estimated_frames = int(duration_sec * fps)
        target_frames = (estimated_frames // 16) * 16  # Round down to nearest multiple of 16

        if target_frames == 0:
            raise ValueError("Video too short: need at least 16 frames for Moonvalley")

        frame_count = 0
        audio_frame_count = 0

        # Decode and re-encode video frames
        if video_stream:
            for frame in input_container.decode(video=0):
                if frame_count >= target_frames:
                    break

                # Re-encode frame
                for packet in video_stream.encode(frame):
                    output_container.mux(packet)
                frame_count += 1

            # Flush encoder
            for packet in video_stream.encode():
                output_container.mux(packet)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Increase the trim duration so that duration_sec * fps >= 16 (e.g. at least 1s at 16fps, ~0.67s at 24fps).
  2. Verify the source clip's average_rate with av or ffprobe; low-fps sources need longer durations.
  3. Check that the duration value is in seconds, not milliseconds or frame counts.
  4. If the source clip itself is shorter than 16 frames, use a longer source video.

Example fix

// before
trimmed = trim_video(video, start_time=0.0, duration=0.4)  # 24fps -> 9 frames

// after
fps = float(video.get_dimensions() and 24)  # know your source fps
min_duration = math.ceil(16 / fps)
trimmed = trim_video(video, start_time=0.0, duration=max(0.4, min_duration))
Defensive patterns

Strategy: validation

Validate before calling

fps = float(input_container.streams.video[0].average_rate)
if int(duration_sec * fps) < 16:
    raise ValueError(f'Duration {duration_sec}s at {fps}fps gives fewer than 16 frames; need >= {16 / fps:.2f}s')

Try / catch

try:
    trimmed = trim_video(video, start_time, duration)
except ValueError as e:
    if 'at least 16 frames' in str(e):
        duration = max(duration, math.ceil(16 / fps))
        trimmed = trim_video(video, start_time, duration)
    else:
        raise

Prevention

When it happens

Trigger: Calling the trim path in comfy_api_nodes/util/conversions.py with a source whose fps * requested duration < 16 frames: e.g. a 5 fps clip trimmed to ~1s (5 frames), a 24 fps clip trimmed to 0.5s (12 frames), or a duration of 0.

Common situations: Trim controls (start + duration) on a Moonvalley image-to-video workflow set too short; a low-fps GIF or screen-recording source; duration accidentally left at 0 or computed from a wrong time unit (milliseconds vs seconds).

Related errors


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