jamiepine/voicebox · warning · HTTPException
CUDA backend already downloaded
Error message
CUDA backend already downloaded
What it means
HTTP 409 raised by POST /backend/download-cuda when cuda.get_cuda_binary_path() returns a non-None path, meaning the CUDA executable already exists inside {data_dir}/backends/cuda/. The endpoint refuses to redownload because the backend is already present. To force a refresh you must delete it first (DELETE /backend/cuda) or rely on the auto-update path that checks version mismatches.
Source
Thrown at backend/routes/cuda.py:34
@router.get("/backend/cuda-status")
async def get_cuda_status():
"""Get CUDA backend download/availability status."""
from ..services import cuda
return cuda.get_cuda_status()
@router.post("/backend/download-cuda")
async def download_cuda_backend():
"""Download the CUDA backend binary."""
from ..services import cuda
unsupported_reason = cuda.get_cuda_download_unsupported_reason()
if unsupported_reason:
raise HTTPException(status_code=409, detail=unsupported_reason)
if cuda.get_cuda_binary_path() is not None:
raise HTTPException(status_code=409, detail="CUDA backend already downloaded")
progress_manager = get_progress_manager()
existing = progress_manager.get_progress(cuda.PROGRESS_KEY)
if existing and existing.get("status") == "downloading":
raise HTTPException(status_code=409, detail="CUDA backend download already in progress")
async def _download():
try:
await cuda.download_cuda_binary()
except Exception as e:
logger.error("CUDA download failed: %s", e)
create_background_task(_download())
return {"message": "CUDA backend download started", "progress_key": "cuda-backend"}
@router.delete("/backend/cuda")
async def delete_cuda_backend():View on GitHub (pinned to 51f49dea19)
Solutions
- If you want a fresh copy, call DELETE /backend/cuda first (only when CUDA is not active).
- To upgrade, rely on the startup auto-update (check_and_update_cuda_binary) which handles version mismatches.
- Check GET /backend/cuda status.available before offering the download action.
Example fix
// before
await fetch('/backend/download-cuda', { method: 'POST' });
// after
const status = await fetch('/backend/cuda').then(r => r.json());
if (status.available) { /* already installed */ return; }
await fetch('/backend/download-cuda', { method: 'POST' }); Defensive patterns
Strategy: validation
Validate before calling
const status = await fetch('/backend/cuda').then(r => r.json());
if (status.available) throw new Error('cuda backend already installed'); Type guard
function isCudaInstalled(s): s is { available: true } { return s?.available === true; } Try / catch
const r = await fetch('/backend/download-cuda', { method:'POST' });
if (r.status === 409) { const { detail } = await r.json(); /* already downloaded | in progress | unsupported */ } Prevention
- Check status.available before offering download.
- Use DELETE (when inactive) + POST to force a refresh.
- Rely on startup auto-update for version upgrades.
When it happens
Trigger: Calling POST /backend/download-cuda after a previous successful download left the binary in place.
Common situations: Clicking download again to 'update'; a reinstall that did not clear the data directory; the auto-update task already populated the binary at startup.
Related errors
- Cannot delete CUDA backend while it is active. Switch to CPU
- CUDA backend download already in progress
- No CUDA backend found to delete
- {exception message from update_channel (ValueError)}
- {exception message from delete_channel (ValueError)}
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/c5af2d495074bdeb.
Report an issue: GitHub.