jamiepine/voicebox · error · ValueError

Whisper model '{model_size}' is not yet downloaded. Open Voi

Error message

Whisper model '{model_size}' is not yet downloaded. Open Voicebox → Settings → Models to download it first.

What it means

Raised by _transcribe_file when the requested whisper model_size is valid but neither loaded nor cached on disk. Specifically: (whisper is not loaded OR its current model_size differs) AND whisper._is_model_cached(model_size) is False. The error points the user to the in-app downloader.

Source

Thrown at backend/mcp_server/tools.py:319

    from ..services import transcribe as transcribe_service
    from ..utils.audio import load_audio

    whisper = transcribe_service.get_whisper_model()
    model_size = model or whisper.model_size
    valid = list(WHISPER_HF_REPOS.keys())
    if model_size not in valid:
        raise ValueError(
            f"Invalid STT model '{model_size}'. Must be one of: {', '.join(valid)}"
        )

    # load_audio is sync; keep the event loop responsive.
    audio, sr = await asyncio.to_thread(load_audio, str(path))
    duration = len(audio) / sr

    if (
        not whisper.is_loaded() or whisper.model_size != model_size
    ) and not whisper._is_model_cached(model_size):
        raise ValueError(
            f"Whisper model '{model_size}' is not yet downloaded. Open "
            "Voicebox → Settings → Models to download it first."
        )

    text = await whisper.transcribe(str(path), language, model_size)
    return {
        "text": text,
        "duration": duration,
        "language": language,
        "model": model_size,
    }

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Open Voicebox → Settings → Models and download the requested whisper size first.
  2. Pre-download programmatically via the backend's load/ensure-cached path before calling transcribe.
  3. Verify the cache directory is writable and persistent across restarts.

Example fix

// before
voicebox_transcribe(audio_base64=b64, model="large")  # not cached
// after
# in Voicebox: Settings → Models → download 'large', then
voicebox_transcribe(audio_base64=b64, model="large")
Defensive patterns

Strategy: try-catch

Validate before calling

from backend.backends import WHISPER_HF_REPOS
whisper = transcribe_service.get_whisper_model()
loaded_or_cached = whisper.is_loaded() or whisper._is_model_cached(model_size)
if not loaded_or_cached:
    raise RuntimeError(f"whisper {model_size!r} not downloaded; run Settings → Models")
await voicebox_transcribe(audio_base64=b64, model=model_size)

Type guard

def whisper_model_ready(model_size: str) -> bool:
    whisper = transcribe_service.get_whisper_model()
    return whisper.is_loaded() or whisper._is_model_cached(model_size)

Try / catch

try:
    await voicebox_transcribe(audio_base64=b64, model=model_size)
except ValueError as exc:
    if "not yet downloaded" in str(exc):
        # trigger download / fall back to an already-cached size
        await voicebox_transcribe(audio_base64=b64, model=None)
    else:
        raise

Prevention

When it happens

Trigger: First use of a whisper size that was never downloaded; switching to a different size (e.g. base → large) that has not been fetched yet; the cache directory was deleted or moved.

Common situations: Fresh install with no models pre-downloaded; offline machine where the initial download never completed; custom HF_HOME / cache dir that was wiped; selecting a heavier model than was ever pulled.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/7fad5999e6c5a92b. Report an issue: GitHub.