{"record":{"id":"18ff70cba6fc732d","repo":"jamiepine/voicebox","slug":"cannot-delete-rocm-backend-while-it-is-active-swi","errorCode":null,"errorMessage":"Cannot delete ROCm backend while it is active. Switch to CPU first.","messagePattern":"Cannot delete ROCm backend while it is active\\. Switch to CPU first\\.","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"warning","filePath":"backend/routes/rocm.py","lineNumber":50,"sourceCode":"        raise HTTPException(status_code=409, detail=\"ROCm backend download already in progress\")\n\n    async def _download():\n        try:\n            await rocm.download_rocm_binary()\n        except Exception as e:\n            logger.error(\"ROCm download failed: %s\", e)\n\n    create_background_task(_download())\n    return {\"message\": \"ROCm backend download started\", \"progress_key\": rocm.PROGRESS_KEY}\n\n\n@router.delete(\"/backend/rocm\")\nasync def delete_rocm_backend():\n    \"\"\"Delete the downloaded ROCm backend binary.\"\"\"\n    from ..services import rocm\n\n    if rocm.is_rocm_active():\n        raise HTTPException(\n            status_code=409,\n            detail=\"Cannot delete ROCm backend while it is active. Switch to CPU first.\",\n        )\n\n    deleted = await rocm.delete_rocm_binary()\n    if not deleted:\n        raise HTTPException(status_code=404, detail=\"No ROCm backend found to delete\")\n\n    return {\"message\": \"ROCm backend deleted\"}\n\n\n@router.get(\"/backend/rocm-progress\")\nasync def get_rocm_download_progress():\n    \"\"\"Get ROCm backend download progress via Server-Sent Events.\"\"\"\n    progress_manager = get_progress_manager()\n\n    async def event_generator():\n        async for event in progress_manager.subscribe(\"rocm-backend\"):","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/rocm.py#L32-L68","documentation":"Returned by DELETE /backend/rocm when rocm.is_rocm_active() returns true (HTTP 409). The handler refuses to delete the binary while it is the active backend, to avoid removing code that is currently serving inference. The message instructs switching to CPU first.","triggerScenarios":"Issuing DELETE /backend/rocm while the backend is configured to use ROCm (is_rocm_active() true). Attempting cleanup without first flipping the active backend setting to CPU.","commonSituations":"User uninstalls ROCm hardware/driver and wants to reclaim disk but forgot to switch the backend selector. Automation script that deletes backends without checking active state.","solutions":["Switch the active backend to CPU via the backend settings endpoint, confirm is_rocm_active() is false, then call DELETE /backend/rocm.","Verify the switch completed before retrying the delete.","In automation, check the active-backend endpoint first and skip/switch as needed.","Do not retry the delete on a 409 loop — it will keep failing until the switch takes effect."],"exampleFix":"# before\nawait client.delete('/backend/rocm')\n\n# after\nawait client.post('/backend/switch', json={'backend': 'cpu'})\nawait wait_until(lambda: not await is_rocm_active())\nawait client.delete('/backend/rocm')","handlingStrategy":"validation","validationCode":"async function rocmActive() {\n  const s = await (await fetch('/api/backend/rocm-status')).json();\n  return s.active === true;\n}","typeGuard":"function isRocmActive(s) { return !!s && s.active === true; }","tryCatchPattern":"try { await api.delete('/backend/rocm'); }\ncatch (e) {\n  if (e.response?.status === 409) { await switchToCpu(); await retryDelete(); return; }\n  throw e;\n}","preventionTips":["Switch the active backend to CPU before deleting ROCm.","Verify is_rocm_active() is false before retrying the delete.","In automation, branch on active state instead of looping on 409."],"tags":["fastapi","http","conflict","rocm","backend","rest"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}