jamiepine/voicebox · warning · HTTPException
Cannot delete CUDA backend while it is active. Switch to CPU
Error message
Cannot delete CUDA backend while it is active. Switch to CPU first.
What it means
HTTP 409 raised by DELETE /backend/cuda when cuda.is_cuda_active() returns true, i.e. the current process is itself the CUDA binary (env var VOICEBOX_BACKEND_VARIANT == 'cuda'). Deleting the onedir bundle out from under a running CUDA process would corrupt the active backend, so the endpoint refuses and instructs you to switch to CPU first.
Source
Thrown at backend/routes/cuda.py:57
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():
"""Delete the downloaded CUDA backend binary."""
from ..services import cuda
if cuda.is_cuda_active():
raise HTTPException(
status_code=409,
detail="Cannot delete CUDA backend while it is active. Switch to CPU first.",
)
deleted = await cuda.delete_cuda_binary()
if not deleted:
raise HTTPException(status_code=404, detail="No CUDA backend found to delete")
return {"message": "CUDA backend deleted"}
@router.get("/backend/cuda-progress")
async def get_cuda_download_progress():
"""Get CUDA backend download progress via Server-Sent Events."""
progress_manager = get_progress_manager()
async def event_generator():
async for event in progress_manager.subscribe("cuda-backend"):View on GitHub (pinned to 51f49dea19)
Solutions
- Restart the server on the CPU backend (unset/switch VOICEBOX_BACKEND_VARIANT), then issue DELETE /backend/cuda.
- For upgrades, prefer letting startup auto-update handle it rather than manual delete while active.
- Check GET /backend/cuda status.active before offering the delete action.
Example fix
// before
await fetch('/backend/cuda', { method: 'DELETE' });
// after
const status = await fetch('/backend/cuda').then(r => r.json());
if (status.active) { alert('Switch to the CPU backend before deleting CUDA'); return; }
await fetch('/backend/cuda', { method: 'DELETE' }); Defensive patterns
Strategy: validation
Validate before calling
const status = await fetch('/backend/cuda').then(r => r.json());
if (status.active) throw new Error('switch to CPU backend before deleting'); Type guard
function isCudaActive(s): s is { active: true } { return s?.active === true; } Try / catch
const r = await fetch('/backend/cuda', { method:'DELETE' });
if (r.status === 409) { const { detail } = await r.json(); /* instructs CPU switch */ } Prevention
- Restart on the CPU backend before deleting CUDA.
- Hide delete while status.active is true.
- Prefer auto-update over manual delete-while-running.
When it happens
Trigger: Calling DELETE /backend/cuda while the server is running as the CUDA variant (the process was launched from the downloaded CUDA executable).
Common situations: Trying to free disk or force an update without first restarting on CPU; an update script running inside the CUDA backend process.
Related errors
- CUDA backend already downloaded
- 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/57cdd8d38718a73b.
Report an issue: GitHub.