jamiepine/voicebox · warning · HTTPException
ROCm backend download already in progress
Error message
ROCm backend download already in progress
What it means
Returned by POST /backend/download-rocm when an existing progress entry for rocm.PROGRESS_KEY already has status 'downloading' or 'extracting' (HTTP 409). The handler reads progress_manager.get_progress and treats any in-flight state as a conflict, preventing concurrent downloads. It is a deliberate guard, not a transient failure.
Source
Thrown at backend/routes/rocm.py:32
@router.get("/backend/rocm-status")
async def get_rocm_status():
"""Get ROCm backend download/availability status."""
from ..services import rocm
return rocm.get_rocm_status()
@router.post("/backend/download-rocm")
async def download_rocm_backend():
"""Download the ROCm backend binary."""
from ..services import rocm
progress_manager = get_progress_manager()
existing = progress_manager.get_progress(rocm.PROGRESS_KEY)
if existing and existing.get("status") in {"downloading", "extracting"}:
raise HTTPException(status_code=409, detail="ROCm backend download already in progress")
async def _download():
try:
await rocm.download_rocm_binary()
except Exception as e:
logger.error("ROCm download failed: %s", e)
create_background_task(_download())
return {"message": "ROCm backend download started", "progress_key": rocm.PROGRESS_KEY}
@router.delete("/backend/rocm")
async def delete_rocm_backend():
"""Delete the downloaded ROCm backend binary."""
from ..services import rocm
if rocm.is_rocm_active():
raise HTTPException(View on GitHub (pinned to 51f49dea19)
Solutions
- Poll GET /backend/rocm-progress (SSE) to observe the existing download's status before re-issuing POST.
- If the status is genuinely stuck ('downloading' indefinitely after a crash), reset the progress entry via the service or restart the backend, then retry.
- Disable the download button in the UI while status is downloading/extracting.
- Treat 409 as 'already started, subscribe to progress' rather than an error to retry.
Example fix
// before
await api.post('/backend/download-rocm');
// after
const status = await getRocmStatus();
if (status === 'downloading' || status === 'extracting') {
return subscribeToProgress();
}
await api.post('/backend/download-rocm'); Defensive patterns
Strategy: retry
Validate before calling
async function rocmDownloadActive() {
const s = await (await fetch('/api/backend/rocm-status')).json();
return s.status === 'downloading' || s.status === 'extracting';
} Type guard
function isRocmInProgress(s) { return s && (s.status === 'downloading' || s.status === 'extracting'); } Try / catch
try { await api.post('/backend/download-rocm'); }
catch (e) {
if (e.response?.status === 409) { await subscribeToProgress(); return; }
throw e;
} Prevention
- Poll /backend/rocm-progress before starting a download.
- Disable the download button while status is downloading/extracting.
- If progress is stuck after a crash, reset the entry or restart the backend before retrying.
When it happens
Trigger: Calling download-rocm while a previous download/extract is still running. A prior download task crashed without updating progress status away from 'downloading'/'extracting', leaving a stale in-flight entry.
Common situations: User double-clicks the download button. Frontend retries on a slow network without checking progress. Background task died (process restart) but progress status was never reset to failed/done.
Related errors
- Cannot delete ROCm backend while it is active. Switch to CPU
- No ROCm backend found to delete
- {exception message from update_channel (ValueError)}
- {exception message from delete_channel (ValueError)}
- CUDA backend already downloaded
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/5ac9a00f1b3d7bd8.
Report an issue: GitHub.