jamiepine/voicebox · error · HTTPException
{e}
Error message
{e} What it means
500 from POST /models/load. The endpoint calls tts.get_tts_model().load_model_async(model_size) inside a bare except Exception and re-raises with detail=str(e) — i.e. the raw exception text is forwarded to the client. model_size defaults to '1.7B' (a query parameter, not a JSON body). Failure modes include unsupported size for the current backend, network/HuggingFace download errors, VRAM exhaustion, and weight-loading failures.
Source
Thrown at backend/routes/models.py:60
copied_so_far,
total_bytes,
filename=item.name,
status="downloading",
)
return copied_so_far
@router.post("/models/load")
async def load_model(model_size: str = "1.7B"):
"""Manually load TTS model."""
from ..services import tts
try:
tts_model = tts.get_tts_model()
await tts_model.load_model_async(model_size)
return {"message": f"Model {model_size} loaded successfully"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/models/unload")
async def unload_model():
"""Unload the default Qwen TTS model to free memory."""
from ..services import tts
try:
tts.unload_tts_model()
return {"message": "Model unloaded successfully"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/models/{model_name}/unload")
async def unload_model_by_name(model_name: str):
"""Unload a specific model from memory without deleting it from disk."""
from ..backends import get_model_config, unload_model_by_configView on GitHub (pinned to 51f49dea19)
Solutions
- Read the detail string — this endpoint leaks the underlying message, which usually names the real cause (size unsupported, network, OOM).
- Call GET /models/status to see which sizes are valid and already cached before loading.
- Free memory first with POST /models/unload, then retry the load.
- Confirm the model_size matches a registry value (e.g. 0.6B/1.7B/4B for Qwen TTS) and that your backend type supports it.
Example fix
# before curl -X POST 'http://localhost:8000/models/load?model_size=7B' # after curl -X POST 'http://localhost:8000/models/load?model_size=1.7B'
Defensive patterns
Strategy: validation
Validate before calling
const VALID_TTS_SIZES = ['0.6B','1.7B','4B']; // confirm against GET /models/status
async function loadTts(size: string) {
if (!VALID_TTS_SIZES.includes(size)) throw new Error(`Unsupported size: ${size}`);
const res = await fetch(`/models/load?model_size=${encodeURIComponent(size)}`, {method:'POST'});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(`Load failed: ${err.detail ?? res.status}`);
}
return res.json();
} Try / catch
try {
await loadTts('1.7B');
} catch (e) {
// e.message contains the leaked detail — inspect for OOM/network/unsupported-size
if (/out of memory|VRAM|CUDA/i.test(e.message)) { await fetch('/models/unload',{method:'POST'}); await loadTts('0.6B'); }
else throw e;
} Prevention
- Always confirm the size is supported for your backend_type via /models/status before loading.
- Unload before loading a different size to avoid VRAM contention.
- Remember this endpoint leaks the underlying error text — don't log it where users can read sensitive paths.
When it happens
Trigger: POST /models/load?model_size=7B (unsupported size); load while offline and the size isn't cached; load a size that exceeds available VRAM; concurrent load already in progress; mlx backend asked for a pytorch-only size.
Common situations: First-run download on a flaky connection; wrong default size after a backend switch (mlx vs pytorch); user manually invoked load on a size the registry doesn't expose; disk full in the HF cache.
Related errors
- Failed to delete model: {str(e)}
- Failed to delete model cache directory: {str(e)}
- captures.noTranscriptError
- Model ${model_size} is not downloaded yet. Use /generate to
- Model {model_size} is not downloaded yet. Use /generate to t
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/22ce10ce188430b2.
Report an issue: GitHub.