{"record":{"id":"afc1f9a9c944dc54","repo":"unslothai/unsloth","slug":"training-is-still-running-stop-training-and-wait","errorCode":null,"errorMessage":"Training is still running. Stop training and wait for it to finish before resetting.","messagePattern":"Training is still running\\. Stop training and wait for it to finish before resetting\\.","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"warning","filePath":"studio/backend/routes/training.py","lineNumber":1808,"sourceCode":"            log = logger,\n        )\n\n\n@router.post(\"/reset\")\nasync def reset_training(\n    body: Optional[TrainingResetRequest] = None, current_subject: str = Depends(get_current_subject)\n):\n    \"\"\"Reset training state so the user can return to configuration.\"\"\"\n    try:\n        backend = get_training_backend()\n        result = await asyncio.to_thread(\n            backend.reset_training_state,\n            expected_job_id = body.expected_job_id if body is not None else None,\n        )\n        if result == \"superseded\":\n            return {\"status\": \"superseded\"}\n        if result == \"active\":\n            raise HTTPException(\n                status_code = 409,\n                detail = \"Training is still running. Stop training and wait for it to finish before resetting.\",\n            )\n        return {\"status\": \"ok\"}\n    except HTTPException:\n        raise\n    except Exception as e:\n        raise log_and_http_error(\n            e,\n            500,\n            \"Failed to reset training\",\n            event = \"training.reset_failed\",\n            log = logger,\n        )\n\n\ndef _training_status_identity(backend) -> TrainingStatusIdentitySnapshot:\n    snapshot = getattr(backend, \"training_status_identity\", None)","sourceCodeStart":1790,"sourceCodeEnd":1826,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/training.py#L1790-L1826","documentation":"HTTP 409 from the reset endpoint when backend.reset_training_state returns 'active': training is currently running and the backend refuses to reset training state (which would discard progress/configuration) underneath a live run. The user must stop training and let it fully finish before resetting.","triggerScenarios":"POST /training/reset while a training subprocess is active — including the window where a stop was requested but the run has not yet halted at its next safe step.","commonSituations":"Clicking 'reset' right after clicking 'stop' without waiting for the stop to take effect; a background job whose shutdown takes seconds to minutes for large models.","solutions":["Stop training first (POST /training/stop) and poll /training/status until it reports the run is finished/idle.","Then retry the reset request.","If status stays active unusually long, check the training log for a hung subprocess before forcing anything."],"exampleFix":"// before\nawait post('/training/stop', {save: true})\nawait post('/training/reset')  // 409: still running\n// after\nawait post('/training/stop', {save: true})\nwhile ((await get('/training/status')).is_active) await sleep(2000)\nawait post('/training/reset')","handlingStrategy":"validation","validationCode":"const status = await get('/training/status')\nif (status.is_active) throw new Error('Stop training and wait for it to finish before resetting')\nawait post('/training/reset', body)","typeGuard":null,"tryCatchPattern":"try { await post('/training/reset', body) } catch (e) { if (e.status === 409 && /still running/.test(e.detail)) { await post('/training/stop', {save: true}); await waitUntilIdle(); return post('/training/reset', body) } throw e }","preventionTips":["Disable the reset button in the UI while a run is active or a stop is pending.","After requesting a stop, poll status until the run reports finished before resetting."],"tags":["reset","lifecycle","conflict","http-409"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}