{"record":{"id":"d907934cd9f9cd24","repo":"unslothai/unsloth","slug":"model-id-is-still-cancelling-try-again-in-a-m-d90793","errorCode":null,"errorMessage":"'{model_id}' is still cancelling; try again in a moment.","messagePattern":"'(.+?)' is still cancelling; try again in a moment\\.","errorType":"http","errorClass":"SttModelIdError","httpStatus":422,"severity":"warning","filePath":"studio/backend/core/inference/stt_sidecar.py","lineNumber":800,"sourceCode":"            return False, stderr\n        detail = stderr.decode(\"utf-8\", \"replace\").strip()\n        raise SttModelCompatibilityError(f\"Download worker failed for '{self._repo}': {detail}\")\n\n    def start(\n        self,\n        model_id: str,\n        hf_token: Optional[str] = None,\n        revision: Optional[str] = None,\n    ) -> None:\n        model_id = resolve_model_id(model_id)\n        hub_cache = _capture_stt_hub_cache()\n        with self._lock:\n            if self._thread is not None and self._thread.is_alive():\n                if self._model_id == model_id:\n                    # Joining a cancelling run would silently download nothing.\n                    if not self._cancelled:\n                        return\n                    raise SttModelIdError(\n                        f\"'{model_id}' is still cancelling; try again in a moment.\"\n                    )\n                raise SttModelIdError(\n                    f\"Another dictation model ('{self._model_id}') is still \"\n                    \"downloading; wait for it to finish.\"\n                )\n            self._model_id = model_id\n            self._repo = resolve_model_repo(model_id)\n            self._revision = None\n            self._hub_cache = hub_cache\n            self._error = None\n            self._total_bytes = None\n            self._selected_files = ()\n            self._complete = False\n            self._cancelled = False\n            self._process = None\n            thread = threading.Thread(\n                target = self._run,","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/stt_sidecar.py#L782-L818","documentation":"Raised by the STT download manager when you request a download for a model whose previous download thread is still alive and flagged as cancelled. The manager refuses to join a cancelling run because doing so would silently download nothing, so it tells you to retry once the cancel finishes. It is a transient state guard, not a permanent failure.","triggerScenarios":"Calling the download API for model X immediately after calling cancel on a download of the same model X, while the worker thread has not yet exited (self._thread.is_alive() and self._cancelled is True and self._model_id == model_id).","commonSituations":"A UI 'Cancel download' button followed quickly by 'Download again' for the same dictation model; rapid toggling between models in Settings; automated retry loops that cancel and restart downloads without waiting.","solutions":["Wait a moment and retry the same download call; the cancelling thread exits on its own and the next call proceeds.","Poll or await the previous cancel completing (thread no longer alive) before issuing the new download request.","In UI code, disable the Download button while a cancel for the same model is in flight instead of firing immediately."],"exampleFix":"// before\ndownloader.cancel(model_id);\ndownloader.download(model_id);  // raises SttModelIdError\n// after\ndownloader.cancel(model_id);\nwait_until_thread_exits();  // or debounce the UI\ndownloader.download(model_id);","handlingStrategy":"retry","validationCode":"with downloader._lock:\n    busy = downloader._thread is not None and downloader._thread.is_alive() and downloader._cancelled\n# only call download() when busy is False","typeGuard":"def is_cancel_in_flight(d) -> bool:\n    with d._lock:\n        return d._thread is not None and d._thread.is_alive() and d._cancelled","tryCatchPattern":"for attempt in range(5):\n    try:\n        downloader.download(model_id); break\n    except SttModelIdError as e:\n        if \"still cancelling\" not in str(e): raise\n        time.sleep(0.5)","preventionTips":["Debounce the Download button after Cancel until the cancel completes","Never join or reuse the download thread yourself; let the manager reach idle state","Treat 'still cancelling' as transient state, never surface it as a hard failure"],"tags":["stt","download","cancellation","transient","threading"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}