{"record":{"id":"79c209c4b10b53ad","repo":"Comfy-Org/ComfyUI","slug":"audio-duration-must-be-between-2-and-20-seconds-g","errorCode":null,"errorMessage":"Audio duration must be between 2 and 20 seconds, got {audio_duration:.1f}s.","messagePattern":"Audio duration must be between 2 and 20 seconds, got (.+?)s\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"comfy_api_nodes/nodes_ltxv.py","lineNumber":564,"sourceCode":"                IO.Hidden.unique_id,\n            ],\n            is_api_node=True,\n            price_badge=V25_A2V_PRICE_BADGE,\n        )\n\n    @classmethod\n    async def execute(\n        cls,\n        audio: Input.Audio,\n        model: dict,\n        prompt: str,\n        seed: int = 42,\n        image: Input.Image | None = None,\n    ) -> IO.NodeOutput:\n        validate_string(prompt, min_length=1, max_length=10000)\n        audio_duration = audio[\"waveform\"].shape[-1] / audio[\"sample_rate\"]\n        if not 2 <= audio_duration <= 20:\n            raise ValueError(f\"Audio duration must be between 2 and 20 seconds, got {audio_duration:.1f}s.\")\n        image_uri = None\n        if image is not None:\n            if get_number_of_images(image) != 1:\n                raise ValueError(\"Currently only one input image is supported.\")\n            image_uri = (await upload_images_to_comfyapi(cls, image, max_images=1, mime_type=\"image/png\"))[0]\n        return await _v25_submit_and_poll(\n            cls,\n            \"audio-to-video\",\n            AudioToVideoRequest(\n                prompt=prompt,\n                model=V25_MODELS_MAP[model[\"model\"]],\n                resolution=model[\"resolution\"],\n                audio_uri=await upload_audio_to_comfyapi(cls, audio),\n                image_uri=image_uri,\n            ),\n        )\n\n","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_ltxv.py#L546-L582","documentation":"Client-side ValueError in the v2.5 LTX audio-to-video node: the input audio's duration, computed as waveform length / sample_rate, must be between 2 and 20 seconds inclusive. Out-of-range audio is rejected before any upload or API call.","triggerScenarios":"Executing the audio-to-video node with audio['waveform'].shape[-1] / audio['sample_rate'] < 2 or > 20 — e.g. a 1-second clip, a 30-second song, or audio loaded with a wrong sample_rate metadata making the computed duration fall outside the window.","commonSituations":"Trimming music too aggressively (< 2s); feeding full songs (> 20s); audio tensors with padded silence inflating duration; mismatched sample_rate between loader and tensor.","solutions":["Trim or pad the audio to 2–20 seconds before the node.","Verify sample_rate matches the actual waveform rate so the duration computation is correct.","Remove trailing silence/padding that inflates duration past 20s."],"exampleFix":"// before: 30s clip\naudio = load_audio(\"song.wav\")  # 30.0s -> raises\n// after: trim to 10s\nwaveform = audio[\"waveform\"][..., : audio[\"sample_rate\"] * 10]\naudio = {\"waveform\": waveform, \"sample_rate\": audio[\"sample_rate\"]}  # 10.0s -> passes","handlingStrategy":"validation","validationCode":"dur = audio[\"waveform\"].shape[-1] / audio[\"sample_rate\"]\nif not 2 <= dur <= 20:\n    raise ValueError(f\"Trim audio to 2-20s (got {dur:.1f}s)\")","typeGuard":"def audio_within_ltx_range(audio: dict) -> bool:\n    d = audio[\"waveform\"].shape[-1] / audio[\"sample_rate\"]\n    return 2 <= d <= 20","tryCatchPattern":null,"preventionTips":["Trim source audio to the 2-20s window before wiring it in.","Strip padding/silence that inflates duration.","Confirm sample_rate metadata matches the waveform."],"tags":["ltx","api-nodes","validation","audio","duration","pre-flight"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}