invoke-ai/InvokeAI · error · ValueError

Reference-image dimensions must be multiples of 8 (got {widt

Error message

Reference-image dimensions must be multiples of 8 (got {width}x{height}).

What it means

preprocess_reference_image resizes a PIL image to (width, height) for the Wan VAE, which requires spatial dims aligned to the model's 8x downsampling factor. If either dimension is not a multiple of 8, the library raises this ValueError before touching the VAE, preventing silent latent misalignment or decoder crashes.

Source

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

with ``num_frames=1`` and ``expand_timesteps=False`` (the defaults for
single-frame image generation).
"""

import torch
import torchvision.transforms.functional as TF
from diffusers.models.autoencoders import AutoencoderKLWan
from PIL import Image

# Wan 2.2 VAE temporal scale factor — single frame still consumes a 4-position
# slice of the mask tensor, which is why the mask contributes 4 channels.
_WAN_VAE_TEMPORAL_SCALE = 4


def preprocess_reference_image(image: Image.Image, width: int, height: int) -> torch.Tensor:
    """Resize a PIL image to (width, height) and return a normalised [-1, 1]
    tensor of shape ``[1, 3, 1, height, width]`` ready for ``AutoencoderKLWan.encode``."""
    if width % 8 != 0 or height % 8 != 0:
        raise ValueError(f"Reference-image dimensions must be multiples of 8 (got {width}x{height}).")
    resized = image.convert("RGB").resize((width, height), Image.LANCZOS)
    # [0, 1] CHW float tensor.
    pixel = TF.to_tensor(resized)
    # Scale to [-1, 1] to match the Wan VAE's expected input range.
    pixel = pixel * 2.0 - 1.0
    # [3, H, W] -> [1, 3, 1, H, W]: add batch + temporal dims.
    return pixel.unsqueeze(0).unsqueeze(2)


def encode_reference_image_to_ti2v_condition(
    image: Image.Image,
    vae: AutoencoderKLWan,
    width: int,
    height: int,
    device: torch.device,
    dtype: torch.dtype,
) -> torch.Tensor:
    """Build the TI2V-5B-style reference condition tensor.

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Round both dims down to the nearest multiple of 8: width = (width // 8) * 8; height = (height // 8) * 8.
  2. Use a standard Wan resolution that is a multiple of 8 (e.g. 1280x720, 832x480).
  3. If dimensions come from user input or config, validate/normalize them before calling the extension.

Example fix

// before
w, h = image.size  # e.g. 1023x681
pixel = preprocess_reference_image(image, w, h)
// after
w = (image.size[0] // 8) * 8
h = (image.size[1] // 8) * 8
pixel = preprocess_reference_image(image, w, h)
Defensive patterns

Strategy: validation

Validate before calling

width = (width // 8) * 8
height = (height // 8) * 8
assert width % 8 == 0 and height % 8 == 0 and width > 0 and height > 0
pixel = preprocess_reference_image(image, width, height)

Try / catch

try:
    pixel = preprocess_reference_image(image, w, h)
except ValueError as e:
    if "multiples of 8" in str(e):
        pixel = preprocess_reference_image(image, (w // 8) * 8, (h // 8) * 8)

Prevention

When it happens

Trigger: Calling preprocess_reference_image directly, or indirectly via encode_reference_image_to_ti2v_condition / encode_reference_image_to_condition / encode_reference_image_to_video_condition, with width or height such that width % 8 != 0 or height % 8 != 0 (e.g. 517x369).

Common situations: Deriving dimensions from the source image's native size, rounding a computed aspect-preserving size with int() instead of rounding down to a multiple of 8, hand-entering resolutions from other models with different patch factors.

Related errors


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