Comfy-Org/ComfyUI · error · ValueError

SeedVR2 expected {name} to be 5-D native latent, got shape {

Error message

SeedVR2 expected {name} to be 5-D native latent, got shape {tuple(x.shape)}.

What it means

SeedVR2 is a video restoration transformer: every latent it touches must be a 5-D native video tensor [B, C, T, H, W]. _check_seedvr2_video_latent raises when ndim != 5, catching 4-D image latents ([B,C,H,W]) or already-flattened token streams before they hit the video reshape logic.

Source

Thrown at comfy/ldm/seedvr/model.py:1263

        if context.shape[0] % 2 != 0:
            raise ValueError(f"SeedVR2 expected an even text-conditioning batch, got shape {tuple(context.shape)}")
        neg_cond, pos_cond = context.chunk(2, dim=0)
        if pos_cond.shape[0] == 1:
            pos_cond, neg_cond = pos_cond.squeeze(0), neg_cond.squeeze(0)
            return flatten([pos_cond, neg_cond])
        return flatten((*pos_cond.unbind(0), *neg_cond.unbind(0)))

    @staticmethod
    def _seedvr2_is_single_conditioning_branch(cond_or_uncond):
        if cond_or_uncond is None or len(cond_or_uncond) == 0:
            return False
        first = cond_or_uncond[0]
        return all(entry == first for entry in cond_or_uncond)

    @staticmethod
    def _check_seedvr2_video_latent(x, channels, name):
        if x.ndim != 5:
            raise ValueError(f"SeedVR2 expected {name} to be 5-D native latent, got shape {tuple(x.shape)}.")
        if x.shape[1] != channels:
            raise ValueError(f"SeedVR2 expected {name} channels to be {channels}, got shape {tuple(x.shape)}.")
        return x

    def _swap_pos_neg_halves(self, out, cond_or_uncond=None):
        if NaDiT._seedvr2_is_single_conditioning_branch(cond_or_uncond):
            return out
        pos, neg = out.chunk(2, dim=0)
        return torch.cat([neg, pos], dim=0)

    def forward(
        self,
        x,
        timestep,
        context,  # l c
        disable_cache: bool = False,
        **kwargs
    ):

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Give tensors a temporal dimension: x = x.unsqueeze(2) to get [B,C,1,H,W] for single images.
  2. Use the SeedVR2 latent/conditioning nodes, which produce 5-D tensors natively.
  3. For single-image restoration, ensure the frame count also satisfies the T % patch_t == 1 rule (1 frame is valid).
  4. Audit any custom adapters that strip or drop the time dimension.

Example fix

# before
x = image_latent          # [B, C, H, W]
out = model(x, ...)
# after
x = image_latent.unsqueeze(2)  # [B, C, 1, H, W]
out = model(x, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

def ensure_video_latent(x):
    if x.dim() == 4:
        x = x.unsqueeze(2)  # image -> [B, C, 1, H, W]
    if x.dim() != 5:
        raise ValueError(f"SeedVR2 needs a 5-D latent [B,C,T,H,W], got {tuple(x.shape)}")
    return x

Type guard

def is_seedvr2_video_latent(x) -> bool:
    import torch
    return torch.is_tensor(x) and x.dim() == 5

Prevention

When it happens

Trigger: Passing a standard 4-D image latent to SeedVR2 forward; passing the 'condition' kwarg a 4-D tensor from an image VAE encode; feeding output of a previous flatten() step back in as input.

Common situations: Trying to use a video-restoration model on a single image without the [B,C,1,H,W] video layout; mixing image workflow tensors into the SeedVR2 path; converting workflows from image models without adding the temporal dimension.

Related errors


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