invoke-ai/InvokeAI · error · ValueError

Wan latents-to-video requires batch size 1; got {latents.sha

Error message

Wan latents-to-video requires batch size 1; got {latents.shape[0]}.

What it means

_validate_video_latent_batch enforces batch size 1 because the Wan VAE decode and frame-writing path (_FrameWriter) handles exactly one video per invocation. Any latent tensor whose first dimension is not 1 raises this ValueError before any expensive model loading occurs.

Source

Thrown at invokeai/app/invocations/wan_latents_to_video.py:48

)
from invokeai.app.invocations.model import VAEField
from invokeai.app.invocations.primitives import VideoOutput
from invokeai.app.services.session_processor.session_processor_common import CanceledException
from invokeai.app.services.shared.invocation_context import InvocationContext
from invokeai.app.util.video_encoding import make_mp4_writer
from invokeai.backend.model_manager.load.model_cache.utils import get_effective_device
from invokeai.backend.util.devices import TorchDevice
from invokeai.backend.util.vae_working_memory import estimate_vae_working_memory_wan
from invokeai.backend.wan.vae_decode import iter_wan_vae_decode_chunks


class _FrameWriter(Protocol):
    def append_data(self, frame: np.ndarray) -> None: ...


def _validate_video_latent_batch(latents: torch.Tensor) -> None:
    if latents.ndim in (4, 5) and latents.shape[0] != 1:
        raise ValueError(f"Wan latents-to-video requires batch size 1; got {latents.shape[0]}.")


def _iter_decoded_frames(decoded: torch.Tensor) -> Iterator[np.ndarray]:
    for index in range(decoded.shape[1]):
        frame = decoded[:, index]
        frame = frame.clamp(-1, 1).permute(1, 2, 0).cpu().float()
        yield (127.5 * (frame + 1.0)).round().clamp(0, 255).byte().numpy()


def _write_video_frames(writer: _FrameWriter, frames: Iterable[np.ndarray], is_canceled: Callable[[], bool]) -> None:
    frames_iter = iter(frames)
    while True:
        if is_canceled():
            raise CanceledException
        try:
            frame = next(frames_iter)
        except StopIteration:
            return

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Set the upstream generation batch size to 1 before producing latents.
  2. If multiple samples are needed, split the latents and call the node once per sample (loop over latents[i:i+1]).
  3. Keep the video pipeline single-sample; generate variation via seeds instead of batching.

Example fix

// before
video = wan_latents_to_video(latents=batched_latents)  # shape [4, C, T, H, W]
// after
for i in range(batched_latents.shape[0]):
    video = wan_latents_to_video(latents=batched_latents[i:i+1])
Defensive patterns

Strategy: validation

Validate before calling

if latents.ndim in (4, 5) and latents.shape[0] != 1:
    raise ValueError(f"Wan video node needs batch size 1, got {latents.shape[0]}; loop over samples instead.")

Type guard

def is_single_video_batch(latents) -> bool:
    return latents.ndim in (4, 5) and latents.shape[0] == 1

Try / catch

try:
    video = node.invoke(context)
except ValueError as e:
    if "requires batch size 1" in str(e):
        for i in range(latents.shape[0]):
            process_video(node, latents[i:i+1])
    else:
        raise

Prevention

When it happens

Trigger: Passing a latent tensor with latents.shape[0] > 1 (4D or 5D) into wan_latents_to_video, either directly from a batched denoiser run or by wiring a batch>1 latents output into the node.

Common situations: Batch generation upstream (scheduler with num_samples>1) feeding the video node; users expecting per-sample video output; copied diffusion-image workflows where batch>1 is normal.

Related errors


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