unslothai/unsloth · error · SttAudioDecodeError
Could not decode the audio.
Error message
Could not decode the audio.
What it means
Raised inside the PyAV decode loop when the opened container exposes no audio stream (container.streams.audio is empty). The bytes opened fine as a media container, but there is no audio track to transcribe — e.g. a video-only file or an empty/misidentified file.
Source
Thrown at studio/backend/core/inference/stt_sidecar.py:1106
)
# Group frames before resampling so short clips need one resampler call
# rather than one per codec frame.
fifo = av.audio.fifo.AudioFifo()
def write_frame(frame) -> None:
nonlocal sample_count
array = frame.to_ndarray()
sample_count += array.size
if sample_count > max_samples:
max_minutes = _MAX_AUDIO_SECONDS // 60
unit = "minute" if max_minutes == 1 else "minutes"
raise SttAudioTooLongError(f"Audio must be {max_minutes} {unit} or shorter.")
raw_buffer.write(array)
try:
with av.open(io.BytesIO(audio), mode = "r", metadata_errors = "ignore") as container:
if not container.streams.audio:
raise SttAudioDecodeError("Could not decode the audio.")
frames = iter(container.decode(audio = 0))
while True:
try:
frame = next(frames)
except StopIteration:
break
except InvalidDataError:
# Skip a corrupt frame rather than fail the whole transcription.
continue
if cancel_event is not None and cancel_event.is_set():
raise SttTranscriptionCancelledError("Transcription cancelled.")
frame.pts = None
fifo.write(frame)
if fifo.samples >= 500000:
for resampled in resampler.resample(fifo.read()):
write_frame(resampled)
if fifo.samples > 0:
for resampled in resampler.resample(fifo.read()):View on GitHub (pinned to 203007d190)
Solutions
- Inspect the file client-side (ffprobe or the browser's audio element) and reject non-audio inputs before upload.
- Check the file size is non-zero and the MIME type is an audio type before calling transcribe.
- If you expect audio from a recorder, verify the recorder actually produced samples (e.g. MediaRecorder ondataavailable events had data).
Example fix
// before
stt.transcribe(file_bytes); // video-only mp4 -> SttAudioDecodeError
// after
if not has_audio_stream(file_bytes): # ffprobe-style probe
return error("File has no audio track")
stt.transcribe(file_bytes) Defensive patterns
Strategy: validation
Validate before calling
import av, io
with av.open(io.BytesIO(audio), mode="r", metadata_errors="ignore") as c:
if not c.streams.audio:
reject("no audio track") Try / catch
try:
stt.transcribe(audio)
except SttAudioDecodeError as e:
if "no audio" in context: reject_upload() # distinguish via upstream probe
else: raise Prevention
- Accept only audio/* MIME types in upload forms
- Probe files with ffprobe/av.open before sending to the API
- Reject zero-byte uploads before they reach transcription
When it happens
Trigger: Calling transcribe() with a video file that has no audio track, a zero-byte or truncated file that PyAV still opens, or a container whose streams are all video/data.
Common situations: Drag-and-drop upload accepting video files; a recorder producing an empty webm when permission was denied; a file with the wrong extension that FFmpeg probes as a non-audio container.
Related errors
- Audio must be {max_minutes} {unit} or shorter.
- load error: {p.get('error')}
- model load did not reach ready within {timeout_s}s
- load error: {p.get('error')}
- No valid audio codes found after START_OF_SPEECH token
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/06424fdf08badca3.
Report an issue: GitHub.