invoke-ai/InvokeAI · error · ValueError

last_image (FLF2V) interpolation requires num_frames > 1.

Error message

last_image (FLF2V) interpolation requires num_frames > 1.

What it means

encode_reference_image_to_video_condition supports FLF2V (first-last-frame-to-video): when a last_image is supplied it is encoded and anchored at the final latent frame. With num_frames == 1 there is no temporal span to interpolate across and only one anchor slot, so the function raises this ValueError instead of silently dropping the last image.

Source

Thrown at invokeai/backend/wan/extensions/wan_ref_image_extension.py:167

    1. The reference image is concatenated with zero pixel-frames to form a
       ``[1, 3, num_frames, H, W]`` pseudo-video — frame 0 carries the start
       image, frame ``num_frames - 1`` carries ``last_image`` (when given), and
       the frames in between are zero. The model was trained against latents
       produced this way; padding in latent space after a 1-frame VAE encode
       would land different values.
    2. The VAE encodes that to ``[1, 16, T_lat, H_lat, W_lat]`` and we
       normalise by the per-channel ``(mean, std)`` from ``vae.config``.
    3. The mask starts in pixel-frame space as ``[1, 1, num_frames, ...]``
       with 1 at the anchored frame(s) and 0 elsewhere — frame 0 for plain I2V,
       or frames 0 and ``num_frames - 1`` for FLF2V. The first frame is repeated
       4× then the whole thing is reshaped/transposed into ``[1, 4, T_lat, ...]``.

    The denoise loop concatenates the result along the channel dim to the
    16-channel noise latents each step, yielding the 36-channel input the
    Wan 2.2 I2V-A14B transformer expects.
    """
    if last_image is not None and num_frames <= 1:
        raise ValueError("last_image (FLF2V) interpolation requires num_frames > 1.")

    vae_dtype = next(iter(vae.parameters())).dtype
    pixel = preprocess_reference_image(image, width=width, height=height).to(
        device=device, dtype=vae_dtype
    )  # [1, 3, 1, H, W]

    # Pad the temporal dim with zero pixel-frames; the VAE handles temporal
    # compression to T_lat. For FLF2V the end image takes the final slot and
    # only the in-between frames are zero.
    if num_frames > 1:
        if last_image is not None:
            last_pixel = preprocess_reference_image(last_image, width=width, height=height).to(
                device=device, dtype=vae_dtype
            )
            middle_zeros = torch.zeros(1, 3, num_frames - 2, height, width, device=device, dtype=vae_dtype)
            video_condition = torch.cat([pixel, middle_zeros, last_pixel], dim=2)
        else:
            zero_frames = torch.zeros(1, 3, num_frames - 1, height, width, device=device, dtype=vae_dtype)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Increase num_frames to at least 2 (Wan typically expects values like 81 for FLF2V).
  2. If you truly want a single frame, pass last_image=None and use the plain I2V path.
  3. Check how num_frames is computed (fps * duration) and ensure rounding yields > 1.

Example fix

// before
encode_reference_image_to_video_condition(..., num_frames=1, last_image=end_img)
// after
encode_reference_image_to_video_condition(..., num_frames=81, last_image=end_img)
Defensive patterns

Strategy: validation

Validate before calling

if last_image is not None and num_frames <= 1:
    raise ValueError("FLF2V needs num_frames > 1; got %d" % num_frames)
latents = encode_reference_image_to_video_condition(..., num_frames=num_frames, last_image=last_image)

Try / catch

try:
    cond = encode_reference_image_to_video_condition(..., num_frames=n, last_image=last_img)
except ValueError as e:
    if "requires num_frames > 1" in str(e):
        cond = encode_reference_image_to_video_condition(..., num_frames=max(2, n), last_image=last_img)

Prevention

When it happens

Trigger: Calling encode_reference_image_to_video_condition with last_image set but num_frames=1 (or 0/negative), e.g. single-frame video generation while also passing an end frame.

Common situations: Configuring a one-frame clip by mistake, computing num_frames from an FPS/duration that rounds to 1, reusing an I2V code path where num_frames defaults to 1 while adding an FLF2V last frame.

Related errors


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