{"record":{"id":"6a38194981bc018c","repo":"Comfy-Org/ComfyUI","slug":"input-audio-must-have-expected-channels-channels","errorCode":null,"errorMessage":"Input audio must have {expected_channels} channels, got {waveform.shape[1]}","messagePattern":"Input audio must have (.+?) channels, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy/ldm/lightricks/vae/audio_vae.py","lineNumber":148,"sourceCode":"        self.preprocessor = AudioPreprocessor(\n            target_sample_rate=autoencoder_config[\"sampling_rate\"],\n            mel_bins=autoencoder_config[\"mel_bins\"],\n            mel_hop_length=autoencoder_config[\"mel_hop_length\"],\n            n_fft=autoencoder_config[\"n_fft\"],\n        )\n\n    def encode(self, audio, sample_rate=44100) -> torch.Tensor:\n        \"\"\"Encode a waveform dictionary into normalized latent tensors.\"\"\"\n\n        waveform = audio\n        waveform_sample_rate = sample_rate\n        input_device = waveform.device\n        expected_channels = self.autoencoder.encoder.in_channels\n        if waveform.shape[1] != expected_channels:\n            if waveform.shape[1] == 1:\n                waveform = waveform.expand(-1, expected_channels, *waveform.shape[2:])\n            else:\n                raise ValueError(\n                    f\"Input audio must have {expected_channels} channels, got {waveform.shape[1]}\"\n                )\n\n        mel_spec = self.preprocessor.waveform_to_mel(\n            waveform, waveform_sample_rate, device=waveform.device\n        )\n\n        latents = self.autoencoder.encode(mel_spec)\n        posterior = DiagonalGaussianDistribution(latents)\n        latent_mode = posterior.mode()\n\n        normalized = self.normalizer.normalize(latent_mode)\n        return normalized.to(input_device)\n\n    def decode(self, latents: torch.Tensor) -> torch.Tensor:\n        \"\"\"Decode normalized latent tensors into an audio waveform.\"\"\"\n        original_shape = latents.shape\n","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/ldm/lightricks/vae/audio_vae.py#L130-L166","documentation":"The audio VAE encoder has a fixed channel count (self.autoencoder.encoder.in_channels, typically 2 for stereo). A mono waveform is auto-expanded, but anything with a different channel count (3+, or 0) is rejected because the mel preprocessor would produce a malformed spectrogram.","triggerScenarios":"vae.encode(waveform) where waveform is (B, C, T) with C not in {1, expected_channels}; e.g. passing 5.1 audio (6ch), or a tensor laid out (B, T, C) so the channel axis is misread.","commonSituations":"Loading multichannel files, wrong tensor layout from a custom loader, or batching audio with a channels-first vs channels-last mismatch.","solutions":["Convert to stereo first: waveform.convert(2) via torchaudio or torch.mean/tile to 2 channels","Mono is fine as-is (auto-expanded); only other counts fail","Check the tensor is (B, C, T) — transpose if you built (B, T, C)"],"exampleFix":"# before\nlatents = audio_vae.encode(waveform_6ch)  # 6 channels -> ValueError\n# after\nwaveform_2ch = waveform_6ch[:, :2]  # or downmix\nlatents = audio_vae.encode(waveform_2ch)","handlingStrategy":"validation","validationCode":"C = waveform.shape[1]\nexpected = audio_vae.autoencoder.encoder.in_channels\nassert C == 1 or C == expected, (C, expected)","typeGuard":"def audio_channels_ok(waveform: torch.Tensor, expected: int) -> bool:\n    return waveform.dim() >= 2 and waveform.shape[1] in (1, expected)","tryCatchPattern":null,"preventionTips":["Downmix/convert to stereo before encode","Verify tensor layout is (B, C, T) at the loader boundary"],"tags":["ltx","audio-vae","channels","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}