{"record":{"id":"9465979c19bac4b6","repo":"Comfy-Org/ComfyUI","slug":"audiojoin-both-input-audios-must-be-mono","errorCode":null,"errorMessage":"AudioJoin: Both input audios must be mono.","messagePattern":"AudioJoin: Both input audios must be mono\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_audio.py","lineNumber":550,"sourceCode":"                IO.Audio.Output(display_name=\"audio\"),\n            ],\n        )\n\n    @classmethod\n    def execute(cls, audio_left, audio_right) -> IO.NodeOutput:\n        if audio_left is None and audio_right is None:\n            return IO.NodeOutput(None)\n        if audio_left is None:\n            return IO.NodeOutput(audio_right)\n        if audio_right is None:\n            return IO.NodeOutput(audio_left)\n        waveform_left = audio_left[\"waveform\"]\n        sample_rate_left = audio_left[\"sample_rate\"]\n        waveform_right = audio_right[\"waveform\"]\n        sample_rate_right = audio_right[\"sample_rate\"]\n\n        if waveform_left.shape[1] != 1 or waveform_right.shape[1] != 1:\n            raise ValueError(\"AudioJoin: Both input audios must be mono.\")\n\n        # Handle different sample rates by resampling to the higher rate\n        waveform_left, waveform_right, output_sample_rate = match_audio_sample_rates(\n            waveform_left, sample_rate_left, waveform_right, sample_rate_right\n        )\n\n        # Handle different lengths by trimming to the shorter length\n        length_left = waveform_left.shape[-1]\n        length_right = waveform_right.shape[-1]\n\n        if length_left != length_right:\n            min_length = min(length_left, length_right)\n            if length_left > min_length:\n                logging.info(f\"JoinAudioChannels: Trimming left channel from {length_left} to {min_length} samples.\")\n                waveform_left = waveform_left[..., :min_length]\n            if length_right > min_length:\n                logging.info(f\"JoinAudioChannels: Trimming right channel from {length_right} to {min_length} samples.\")\n                waveform_right = waveform_right[..., :min_length]","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_audio.py#L532-L568","documentation":"JoinAudioChannels stacks two mono signals into stereo by slicing channel dim 1; it hard-requires both inputs to have exactly 1 channel. Either input being stereo or multichannel raises before sample-rate matching runs.","triggerScenarios":"Passing a stereo file's audio as audio_left/audio_right; passing 4/6-channel surround audio; upstream nodes that output batched multi-channel tensors where dim 1 > 1.","commonSituations":"Mixing audio from heterogeneous sources (one mono mic, one stereo music bed) into a stereo join; re-using a join template after the source export changed to stereo.","solutions":["Downmix or select a single channel per input first: wav[:, :1, :] or mean over dim 1","Use SplitAudioChannels to extract a mono channel from a stereo input before joining","Re-export sources as mono where a mono-to-stereo placement is intended","Assert both shapes are (B, 1, N) upstream so the failure is caught at the boundary"],"exampleFix":"// before\nstereo = JoinAudioChannels(music_stereo, voice_mono)  # raises\n\n// after\nmusic_mono = {'waveform': music_stereo['waveform'][:, :1, :], 'sample_rate': music_stereo['sample_rate']}\nstereo = JoinAudioChannels(music_mono, voice_mono)","handlingStrategy":"type-guard","validationCode":"def to_mono(audio):\n    wf = audio['waveform']\n    if wf.shape[1] > 1:\n        wf = wf[:, :1, :]  # or wf.mean(dim=1, keepdim=True)\n    return {'waveform': wf, 'sample_rate': audio['sample_rate']}","typeGuard":"def is_mono(audio) -> bool:\n    return audio is not None and audio['waveform'].shape[1] == 1","tryCatchPattern":null,"preventionTips":["Extract a single channel per input before joining","Assert (batch, 1, samples) shape at your adapter boundary","Use SplitAudioChannels to demux stereo before JoinAudioChannels"],"tags":["audio","channels","mono","shape-mismatch"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}