Comfy-Org/ComfyUI · error · ValueError
No audio stream found in response.
Error message
No audio stream found in response.
What it means
audio_bytes_to_audio_input opens the downloaded bytes with PyAV and requires at least one audio stream. If af.streams.audio is empty it raises ValueError('No audio stream found in response.') because there is nothing to decode into a Comfy AUDIO dict.
Source
Thrown at comfy_api_nodes/util/conversions.py:578
def _f32_pcm(wav: torch.Tensor) -> torch.Tensor:
"""Convert audio to float 32 bits PCM format. Copy-paste from nodes_audio.py file."""
if wav.dtype.is_floating_point:
return wav
elif wav.dtype == torch.int16:
return wav.float() / (2**15)
elif wav.dtype == torch.int32:
return wav.float() / (2**31)
raise ValueError(f"Unsupported wav dtype: {wav.dtype}")
def audio_bytes_to_audio_input(audio_bytes: bytes) -> dict:
"""
Decode any common audio container from bytes using PyAV and return
a Comfy AUDIO dict: {"waveform": [1, C, T] float32, "sample_rate": int}.
"""
with av.open(BytesIO(audio_bytes)) as af:
if not af.streams.audio:
raise ValueError("No audio stream found in response.")
stream = af.streams.audio[0]
in_sr = int(stream.codec_context.sample_rate)
out_sr = in_sr
frames: list[torch.Tensor] = []
n_channels = stream.channels or 1
for frame in af.decode(streams=stream.index):
arr = frame.to_ndarray() # shape can be [C, T] or [T, C] or [T]
buf = torch.from_numpy(arr)
if buf.ndim == 1:
buf = buf.unsqueeze(0) # [T] -> [1, T]
elif buf.shape[0] != n_channels and buf.shape[-1] == n_channels:
buf = buf.transpose(0, 1).contiguous() # [T, C] -> [C, T]
elif buf.shape[0] != n_channels:
buf = buf.reshape(-1, n_channels).t().contiguous() # fallback to [C, T]
frames.append(buf)View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Dump the first bytes of the response to a file and inspect with ffprobe or a text editor — if it is JSON/HTML, the upstream call failed, not the audio parsing.
- Check the API node's status/job polling: confirm the job actually completed before the download step.
- Re-run the request and inspect the logged response body in request logs.
- If the file is real audio in an exotic container, re-export it as WAV/MP3 and feed it via Load Audio instead.
Defensive patterns
Strategy: validation
Validate before calling
import av
from io import BytesIO
with av.open(BytesIO(audio_bytes)) as c:
if not c.streams.audio:
# inspect bytes: probably a JSON/HTML error, not audio
preview = audio_bytes[:64]
raise ValueError(f'No audio stream; body starts with: {preview!r}') Try / catch
try:
audio = audio_bytes_to_audio_input(data)
except ValueError as e:
if 'No audio stream' in str(e):
# upstream returned a non-audio body; do not retry blindly
log.error('Non-audio response: %r', data[:200])
raise
raise Prevention
- Check Content-Type of media responses before decoding when the API provides it.
- Confirm the generation job reached a terminal success state before downloading.
- Log the first bytes of unexpected payloads for diagnosis.
When it happens
Trigger: A text-to-music/speech API node downloads the response body and the bytes are not audio-with-a-stream: a video-only MP4, a JSON error object, an HTML error page, or an empty body that still parses as a container.
Common situations: The API returned an error payload with HTTP 200 (async job failed server-side but body is JSON); the endpoint changed to return a zip/manifest instead of raw audio; a CDN intercepting the request; wrong endpoint URL used in a custom node.
Related errors
- Expected waveform tensor shape (1, channels, samples)
- Decoded zero audio frames.
- Minimum cutoff must be larger than zero.
- A cutoff above 0.5 does not make sense.
- Minimum cutoff must be larger than zero.
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/e61ea1b5dfa1ceb5.
Report an issue: GitHub.