{"record":{"id":"acd1733c45e94736","repo":"invoke-ai/InvokeAI","slug":"these-latents-hold-latents-shape-2-frames-of-vi","errorCode":null,"errorMessage":"These latents hold {latents.shape[2]} frames of video; this node decodes a single image. Use 'Latents to Video - Wan 2.2' (wan_l2v) for video latents.","messagePattern":"These latents hold (.+?) frames of video; this node decodes a single image\\. Use 'Latents to Video - Wan 2\\.2' \\(wan_l2v\\) for video latents\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/wan_latents_to_image.py","lineNumber":65,"sourceCode":"    vae: VAEField = InputField(description=FieldDescriptions.vae, input=Input.Connection)\n\n    @torch.no_grad()\n    def invoke(self, context: InvocationContext) -> ImageOutput:\n        latents = context.tensors.load(self.latents.latents_name)\n\n        if latents.ndim not in (4, 5):\n            raise ValueError(\n                f\"Wan latents-to-image expects a 4D or 5D latent tensor [B, C, (T), H, W]; got {tuple(latents.shape)}.\"\n            )\n        if latents.shape[0] != 1:\n            raise ValueError(f\"Wan latents-to-image requires batch size 1; got {latents.shape[0]}.\")\n\n        # This node decodes exactly one image. Multi-frame video latents would otherwise\n        # run the full (expensive) multi-frame VAE decode — under a working-memory\n        # estimate that assumed one frame — and then die in an opaque einops rank error\n        # at the final rearrange. Checked before the VAE is even loaded.\n        if latents.ndim == 5 and latents.shape[2] != 1:\n            raise ValueError(\n                f\"These latents hold {latents.shape[2]} frames of video; this node decodes a single \"\n                \"image. Use 'Latents to Video - Wan 2.2' (wan_l2v) for video latents.\"\n            )\n\n        vae_info = context.models.load(self.vae.vae)\n        if not isinstance(vae_info.model, AutoencoderKLWan):\n            raise TypeError(f\"Expected AutoencoderKLWan for Wan VAE, got {type(vae_info.model).__name__}.\")\n\n        spatial_scale = getattr(vae_info.model.config, \"scale_factor_spatial\", None) or 8\n        estimated_working_memory = estimate_vae_working_memory_wan(\n            operation=\"decode\",\n            vae=vae_info.model,\n            pixel_height=latents.shape[-2] * spatial_scale,\n            pixel_width=latents.shape[-1] * spatial_scale,\n            pixel_frames=1,\n        )\n\n        with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/wan_latents_to_image.py#L47-L83","documentation":"A 5D latent tensor with T > 1 holds multi-frame video. Decoding it here would run the full multi-frame VAE decode under a single-frame working-memory estimate and crash in an opaque einops rank error at the final rearrange. The node checks T == 1 before the VAE is even loaded and directs the user to the Wan 2.2 latents-to-video node.","triggerScenarios":"Passing video latents from a Wan text/image-to-video generation into the image (single-frame) decode node; using a denoise output that produced multiple frames.","commonSituations":"Confusing 'Wan Latents to Image' with 'Latents to Video - Wan 2.2' (wan_l2v) in a video workflow; template edits that swapped the decode node.","solutions":["Use the 'Latents to Video - Wan 2.2' (wan_l2v) node for multi-frame latents","Or squeeze/trim latents to a single frame (latents[:, :, :1]) if you truly want one frame decoded","Fix the workflow wiring so video outputs go to the video decode node"],"exampleFix":"// before\nvideoLatents (T=16) -> wanLatentsToImage  // error\n// after\nvideoLatents -> wanLatentsToVideo (wan_l2v)","handlingStrategy":"validation","validationCode":"if latents.ndim == 5 and latents.shape[2] != 1:\n    raise ValueError(\"multi-frame video latents: use wan_l2v instead\")","typeGuard":"def is_single_frame(t: torch.Tensor) -> bool:\n    return t.ndim == 4 or (t.ndim == 5 and t.shape[2] == 1)","tryCatchPattern":"try:\n    out = wan_latents_to_image.invoke(context)\nexcept ValueError as e:\n    if 'frames of video' in str(e):\n        out = wan_l2v.invoke(context)  # route to video node\n    else:\n        raise","preventionTips":["Route video-generation outputs to wan_l2v, not the image node","Know which node type your workflow produces (image vs video latents)","Keep Wan template workflows intact when swapping decode nodes"],"tags":["invokeai","wan","video-latents","wrong-node"],"backgroundTag":"wrong-node-for-latent-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}