invoke-ai/InvokeAI · error · ValueError

Clip {i} has {n_frames} frames but the requested transitions

Error message

Clip {i} has {n_frames} frames but the requested transitions need {head_want} from its head + {tail_keep} from its tail. Lower transition_frames or use longer clips.

What it means

Thrown when a clip has fewer frames than the sum of head_want and tail_keep required by the neighboring transitions. With transition_frames=tf, each clip must supply ~tf/2 frames at its head and tail for crossfades; short clips cannot support the requested transition. This is a hard validation to prevent index errors.

Source

Thrown at invokeai/app/invocations/video_concat.py:281

                # The clip's first head_want frames are consumed into the boundary blend
                # with the previous clip's tail rather than emitted directly.
                if not head_complete:
                    b_head.append(frame)
                    if len(b_head) == head_want and blend is not None:
                        yield from blend(a_tail, b_head)
                        a_tail = []
                        b_head = []
                        head_complete = True
                    continue
                # Hold back the last tail_keep frames seen so far; anything older is
                # guaranteed not to be part of the next boundary and can be emitted.
                tail_buf.append(frame)
                if len(tail_buf) > tail_keep:
                    yield tail_buf.popleft()
            if n_frames == 0:
                raise ValueError(f"Input video {i} ({self.videos[i].video_name}) decoded to zero frames.")
            if n_frames < head_want + tail_keep:
                raise ValueError(
                    f"Clip {i} has {n_frames} frames but the requested transitions need "
                    f"{head_want} from its head + {tail_keep} from its tail. Lower "
                    f"transition_frames or use longer clips."
                )
            a_tail = list(tail_buf)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Lower transition_frames on the invocation
  2. Use longer source clips
  3. Remove the too-short clip from the chain
  4. Trim fewer frames by switching boundary mode to 'cut' instead of crossfade

Example fix

// before
VideoConcat(videos=[short_clip], transition_frames=48)  # clip has only 20 frames
// after
VideoConcat(videos=[short_clip], transition_frames=8)
Defensive patterns

Strategy: validation

Validate before calling

n = decoder_frame_count(path)
need = transition_frames  # head + tail per boundary approx tf
if n is not None and n < need:
    raise ValueError(f'clip {name} too short: {n} frames < {need} needed')

Try / catch

try:
    out = concat.invoke(context)
except ValueError as e:
    if 'Lower transition_frames or use longer clips' in str(e):
        tf = min(transition_frames, min_clip_frames // 2)
        out = rebuild(transition_frames=tf).invoke(context)
    else:
        raise

Prevention

When it happens

Trigger: invoke() -> _iter_joined_frames: after decoding video i, n_frames < head_want + tail_keep (roughly transition_frames at each boundary).

Common situations: Very short clips (e.g. 1-2 seconds) combined with large transition_frames; three-clip chains where the middle clip needs head+tail simultaneously.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/a13d2e5306c7f855. Report an issue: GitHub.