unslothai/unsloth · error · SttAudioDecodeError
Could not decode the audio.
Error message
Could not decode the audio.
What it means
SttAudioDecodeError raised after a successful HTTP 2xx from whisper-server: the JSON payload's 'text' field is missing or not a string. Despite the decode-sounding message, this is a response-shape failure — the server answered but not with a usable transcription object.
Source
Thrown at studio/backend/core/inference/stt_ggml_sidecar.py:1211
)
payload = json.loads(response.read().decode("utf-8"))
except (SttAudioDecodeError, SttEngineUnavailableError):
raise
except Exception as exc:
# A cancel closes this socket deliberately, so it is not evidence of a broken
# runtime and must not disable the engine.
if cancel_event is None or not cancel_event.is_set():
note_runtime_inference_failure(f"{type(exc).__name__}: {exc}")
raise SttEngineUnavailableError(
"The local transcription runtime did not answer the request. "
"Transcription will use the Transformers engine from now on."
) from exc
finally:
cancel_done.set()
connection.close()
text = payload.get("text")
if not isinstance(text, str):
raise SttAudioDecodeError("Could not decode the audio.")
# It served a transcription, so whatever failed earlier was transient.
clear_runtime_inference_failure()
# whisper.cpp joins segments with newlines; dictation wants one line.
return " ".join(part.strip() for part in text.splitlines() if part.strip()).strip()
_sidecar: Optional[GgmlSttSidecar] = None
def get_ggml_stt_sidecar() -> GgmlSttSidecar:
global _sidecar
if _sidecar is None:
_sidecar = GgmlSttSidecar()
return _sidecar
View on GitHub (pinned to 203007d190)
Solutions
- Retry the transcription once — a transient malformed response is possible under load.
- Ensure the managed whisper.cpp runtime is current (`unsloth studio update`) so the response schema matches what the sidecar parses.
- If reproducible, capture the raw response body and verify it comes from whisper.cpp's server, not another local HTTP service.
Defensive patterns
Strategy: retry
Try / catch
try:
result = sidecar.transcribe(audio, language=lang)
except SttAudioDecodeError as exc:
if "Could not decode" in str(exc):
result = retry_once_or_fallback(audio, lang) # malformed server response
else:
raise Prevention
- Keep whisper.cpp updated so the /inference JSON schema matches the parser.
- Ensure nothing else can answer on the reserved 127.0.0.1 port.
- Log the raw response body when this fires to distinguish schema drift from rogue responders.
When it happens
Trigger: _post_inference reads payload = json.loads(response.read()) and payload.get('text') is not a str — server returned an error body with 200, an empty object, or an unexpected schema from a different whisper-server build.
Common situations: A local process (not whisper.cpp) answered the probe and inference with a different JSON shape; whisper-server build drift changed its response schema; server returned an error envelope with status 200.
Related errors
- The local transcription runtime returned HTTP {response.stat
- STT model '{model}' is not a curated GGUF dictation model. C
- The local transcription runtime is not installed. Run `unslo
- The local transcription runtime is missing its paired ggml l
- '{model_id}' is still cancelling; try again in a moment.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/74b142f8dfed6f85.
Report an issue: GitHub.