jamiepine/voicebox · error · HTTPException
str(e)
Error message
str(e)
What it means
Raised (HTTP 500) by POST /transcribe as the catch-all for any non-HTTPException during transcription (genuine HTTPExceptions, including the 202 'model downloading', are re-raised first). The detail is raw str(e). The body of the handler loads/decodes audio, optionally re-encodes to WAV, and calls whisper_model.transcribe — so the underlying cause is typically a decode failure, a Whisper runtime error, or a model-loading problem that wasn't caught by the is_loaded/_is_model_cached guards.
Source
Thrown at backend/routes/transcription.py:101
status_code=202,
detail={
"message": f"Whisper model {model_size} is being downloaded. Please wait and try again.",
"model_name": progress_model_name,
"downloading": True,
},
)
text = await whisper_model.transcribe(stt_path, language, model_size)
return models.TranscriptionResponse(
text=text,
duration=duration,
)
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
Path(tmp_path).unlink(missing_ok=True)
if stt_path != tmp_path:
Path(stt_path).unlink(missing_ok=True)
View on GitHub (pinned to 51f49dea19)
Solutions
- Read the server traceback — str(e) is only the surface; the logged exception has the frame.
- Validate the upload is non-empty before processing (the route reads in 1MB chunks but doesn't reject empty input).
- Ensure the Whisper model for the chosen size is fully downloaded (let the 202 download flow finish before retrying).
- Replace detail=str(e) with a generic message and log server-side to avoid leaking internals.
- Confirm ffmpeg is installed if inputs include webm/opus/m4a.
Example fix
# before
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# after
except Exception:
logger.exception("transcribe failed for %s", tmp_path)
raise HTTPException(status_code=500, detail="Transcription failed; see server logs") Defensive patterns
Strategy: try-catch
Validate before calling
function looksLikeUsableAudio(file) {
return file && file.size > 1024 && /\.(wav|mp3|m4a|ogg|flac|aac|webm|opus)$/i.test(file.name || '');
}
if (!looksLikeUsableAudio(file)) { notify('Audio file is empty or unsupported'); return; } Type guard
function isNonEmptyAudioFile(file) {
return file instanceof File && file.size > 0 && Boolean(file.name);
} Try / catch
try { await api.transcribe(file, language, model); }
catch (e) {
if (e.status === 500) { notify('Transcription failed; check server logs and audio file'); }
else if (e.status === 202) { notify('Model downloading; retry shortly'); }
else throw e;
} Prevention
- Reject empty/undersized uploads before sending.
- Ensure ffmpeg is installed so exotic containers decode server-side.
- Let the 202 'downloading' flow finish before retrying a model that isn't cached.
- Server-side, log the traceback and return a generic message instead of str(e).
When it happens
Trigger: Uploaded file is zero-length or an unreadable container after the upload read; librosa load succeeds but the re-encoded .stt.wav is malformed; whisper_model.transcribe throws (OOM, unsupported sample rate, incomplete model download despite the cache check).
Common situations: Browser recording truncated/empty; a partially downloaded Whisper model passes _is_model_cached but fails at inference; GPU/MPS OOM on a long file; ffmpeg/audioread backend missing on the host so decode of exotic containers fails inside transcribe.
Related errors
- str(e)
- Failed to clear cache: {str(e)}
- Invalid model size '{model_size}'. Must be one of: {', '.joi
- Invalid STT model '{model_size}'. Must be one of: {', '.join
- Whisper model '{model_size}' is not yet downloaded. Open Voi
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/d979e62f2912b34f.
Report an issue: GitHub.