{"record":{"id":"3fb85fb8a8a8dd28","repo":"unslothai/unsloth","slug":"transcription-cancelled-3fb85f","errorCode":null,"errorMessage":"Transcription cancelled.","messagePattern":"Transcription cancelled\\.","errorType":"http","errorClass":"SttTranscriptionCancelledError","httpStatus":409,"severity":"info","filePath":"studio/backend/core/inference/stt_mtmd_sidecar.py","lineNumber":804,"sourceCode":"        sock.bind((\"127.0.0.1\", 0))\n        return sock, sock.getsockname()[1]\n\n    def _ensure_model_downloaded(self, model_id: str) -> tuple[str, str]:\n        paths = _cached_model_paths(model_id)\n        if paths is None:\n            raise SttModelNotDownloadedError(\n                f\"STT model '{model_id}' is not downloaded. \"\n                \"Download it in Settings, then Voice, before loading it.\"\n            )\n        return paths\n\n    def load(\n        self,\n        model: Optional[str] = None,\n        request_cancel_event: Optional[threading.Event] = None,\n    ) -> None:\n        if request_cancel_event is not None and request_cancel_event.is_set():\n            raise SttTranscriptionCancelledError(\"Transcription cancelled.\")\n        self._raise_if_update_in_progress()\n        model_id = resolve_mtmd_model_id(model)\n        binary = ensure_engine_available()\n        # Startup happens outside _lock (it is slow), so this keeps two callers\n        # from each spawning a server and orphaning the first.\n        with self._start_lock:\n            if request_cancel_event is not None and request_cancel_event.is_set():\n                raise SttTranscriptionCancelledError(\"Transcription cancelled.\")\n            self._raise_if_update_in_progress()\n            self._load_locked(model_id, binary, request_cancel_event)\n\n    def _load_locked(\n        self,\n        model_id: str,\n        binary: str,\n        request_cancel_event: Optional[threading.Event] = None,\n    ) -> None:\n        with self._lock:","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/stt_mtmd_sidecar.py#L786-L822","documentation":"SttTranscriptionCancelledError raised at the top of load(): if the caller passed a request_cancel_event and it is already set, the load aborts before resolving the model or taking _start_lock. It is the cheap first cancellation checkpoint of a load request.","triggerScenarios":"load(model, request_cancel_event=ev) invoked after ev.set() — e.g. the user released/aborted the dictation recording before the load call ran.","commonSituations":"UI cancel racing a background preload; a keep-alive warmup whose owning request was cancelled first; cancel event set during audio decode so the subsequent load sees it set.","solutions":["Treat as expected cancellation: stop the dictation flow, do not retry.","If loads are being cancelled unintentionally, audit who shares the cancel event and its lifetime.","Pass a fresh threading.Event per request so unrelated cancels do not leak between requests."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"```python\nif request_cancel_event is not None and request_cancel_event.is_set():\n    return  # skip the load entirely\n```","typeGuard":null,"tryCatchPattern":"```python\ntry:\n    sidecar.load(model, request_cancel_event=ev)\nexcept SttTranscriptionCancelledError:\n    return {\"status\": \"cancelled\"}\n```","preventionTips":["Check the cancel event before invoking load.","Create a fresh Event per request; never share across requests.","Treat cancellation as a normal control-flow outcome, not an error to log loudly."],"tags":["stt","cancellation","load","sidecar"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}