{"record":{"id":"2c10c2b223585460","repo":"Comfy-Org/ComfyUI","slug":"adding-guide-to-a-combined-av-latent-is-not-suppor","errorCode":null,"errorMessage":"Adding guide to a combined AV latent is not supported.","messagePattern":"Adding guide to a combined AV latent is not supported\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_lt.py","lineNumber":380,"sourceCode":"        # so that RoPE represents the correct middle point of each token.\n        # keyframe_idxs dims: (batch, spatial_dim [t,h,w], token_id, [start, end])\n        # We only adjust h,w (not t) in dim 1, and only end (not start) in dim 3.\n        spatial_end_offset = (latent_downscale_factor - 1) * torch.tensor(\n            scale_factors[1:],\n            device=pixel_coords.device,\n        ).view(1, -1, 1, 1)\n        pixel_coords[:, 1:, :, 1:] += spatial_end_offset.to(pixel_coords.dtype)\n\n        if keyframe_idxs is None:\n            keyframe_idxs = pixel_coords\n        else:\n            keyframe_idxs = torch.cat([keyframe_idxs, pixel_coords], dim=2)\n        return node_helpers.conditioning_set_values(cond, {\"keyframe_idxs\": keyframe_idxs})\n\n    @classmethod\n    def append_keyframe(cls, positive, negative, frame_idx, latent_image, noise_mask, guiding_latent, strength, scale_factors, guide_mask=None, in_channels=128, latent_downscale_factor=1, causal_fix=None):\n        if latent_image.shape[1] != in_channels or guiding_latent.shape[1] != in_channels:\n            raise ValueError(\"Adding guide to a combined AV latent is not supported.\")\n\n        positive = cls.add_keyframe_index(positive, frame_idx, guiding_latent, scale_factors, latent_downscale_factor, causal_fix=causal_fix)\n        negative = cls.add_keyframe_index(negative, frame_idx, guiding_latent, scale_factors, latent_downscale_factor, causal_fix=causal_fix)\n\n        if guide_mask is not None:\n            target_h = max(noise_mask.shape[3], guide_mask.shape[3])\n            target_w = max(noise_mask.shape[4], guide_mask.shape[4])\n\n            if noise_mask.shape[3] == 1 or noise_mask.shape[4] == 1:\n                noise_mask = noise_mask.expand(-1, -1, -1, target_h, target_w)\n\n            if guide_mask.shape[3] == 1 or guide_mask.shape[4] == 1:\n                guide_mask = guide_mask.expand(-1, -1, -1, target_h, target_w)\n            mask = guide_mask - strength\n        else:\n            mask = torch.full(\n                (noise_mask.shape[0], 1, guiding_latent.shape[2], noise_mask.shape[3], noise_mask.shape[4]),\n                max(0.0, 1.0 - strength), # clamp here to amplify only via the attention mask","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_lt.py#L362-L398","documentation":"Raised by LTXGuide.append_keyframe() when either the incoming latent or the guiding latent has a channel dimension different from the expected in_channels (default 128). LTX video latents have 128 channels; a tensor with more channels is a combined audio+video latent (VAE outputs audio channels concatenated), and per-frame guide injection into such a combined latent is not supported.","triggerScenarios":"Feeding the latent from an LTX VAE encode that includes audio (combined AV VAE output, channels > 128) into the append-keyframe guide node; mismatched in_channels parameter (passing 192 while the workflow uses 128-channel latents); using a guide latent encoded with a different VAE channel count than the base latent.","commonSituations":"LTX audio+video workflows where the VAE encode keeps the audio channels; mixing models with different latent channel counts (LTX-2 vs older checkpoints).","solutions":["Use a video-only latent (128 channels) for the guided path — drop the audio channels or encode video without audio.","Make sure in_channels on the node matches the actual VAE latent channels of both latent_image and guiding_latent.","Encode the guide frames with the same VAE as the base latent so channel counts agree."],"exampleFix":"# before\nlatent = av_vae.encode(video_with_audio)  # channels == 128 + audio_ch -> raises\n\n# after\nlatent = video_vae.encode(video)           # channels == 128","handlingStrategy":"validation","validationCode":"IN_CHANNELS = 128\nassert latent_image.shape[1] == IN_CHANNELS and guiding_latent.shape[1] == IN_CHANNELS, (\n    f\"combined AV latent detected ({latent_image.shape[1]} ch); supply a video-only {IN_CHANNELS}-ch latent\")","typeGuard":"def is_video_only_latent(latent, in_channels: int = 128) -> bool:\n    return latent[\"samples\"].shape[1] == in_channels","tryCatchPattern":"try:\n    out = LTXGuide.append_keyframe(positive, negative, frame_idx, latent, ...)\nexcept ValueError as e:\n    if \"combined AV latent\" in str(e):\n        raise ValueError(\"Re-encode without audio so the latent has 128 video channels\") from e\n    raise","preventionTips":["Encode video without audio for guided LTX workflows.","Check latent.shape[1] equals the model's in_channels before guide injection.","Use the same VAE for guide and base latents."],"tags":["ltx","latent","shape","audio","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}