{"record":{"id":"598973fb2ab2d7e2","repo":"unslothai/unsloth","slug":"a-transcription-is-still-running-on-the-current-di","errorCode":null,"errorMessage":"A transcription is still running on the current dictation model. Try again in a moment.","messagePattern":"A transcription is still running on the current dictation model\\. Try again in a moment\\.","errorType":"http","errorClass":"SttModelBusyError","httpStatus":409,"severity":"warning","filePath":"studio/backend/core/inference/stt_mtmd_sidecar.py","lineNumber":853,"sourceCode":"            # so a training start would otherwise see False and wait out the startup in\n            # unload() instead of cancelling this load.\n            cancel_event = (\n                request_cancel_event if request_cancel_event is not None else threading.Event()\n            )\n            self._load_cancel_event = cancel_event\n            self._load_owner_cancel_event = request_cancel_event\n            self._loading = True\n            released = False\n            try:\n                if cancel_event.is_set():\n                    raise SttLoadCancelledError(\"Dictation model loading was cancelled.\")\n                # Before the release: a 409 for a model that is not downloaded\n                # must not cost the user the server they were already using.\n                model_path, mmproj_path = self._ensure_model_downloaded(model_id)\n                # Only when there is a live server to protect: a request against\n                # a server that already died must not block recovery.\n                if self._active_requests and self._process_alive():\n                    raise SttModelBusyError(\n                        \"A transcription is still running on the current dictation model. \"\n                        \"Try again in a moment.\"\n                    )\n                self._release_locked()\n                released = True\n            finally:\n                # Nothing started, so take the announcement back; past here the startup owns it.\n                if not released:\n                    self._loading = False\n                    self._load_cancel_event = None\n                    self._load_owner_cancel_event = None\n            # Re-read last: _release_locked() reaps the old server, which can\n            # take seconds, and training admission that already passed its own\n            # check cannot come back to cancel this load. Publishing _loading\n            # first covers the other order, so between them every training start\n            # either cancels this load or is seen by it.\n            training = _training_active()\n        try:","sourceCodeStart":835,"sourceCodeEnd":871,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/stt_mtmd_sidecar.py#L835-L871","documentation":"SttModelBusyError raised in _load_locked when a model switch is requested while self._active_requests > 0 and the current server process is alive. Switching would tear down a server that is mid-transcription, so the switch is refused instead — and it is refused before _release_locked(), so the user keeps the working server.","triggerScenarios":"Client A is transcribing on model X (active request in flight) while client B calls load(model Y) on the same sidecar instance.","commonSituations":"Two studio windows/tabs dictating with different models; a long recording still uploading while the user changes the voice model in settings; a preload racing a live transcription.","solutions":["Retry the model switch after the in-flight transcription finishes (usually seconds).","Serialize model switches behind a queue so only one switch is attempted at a time.","Keep a single model choice per session to avoid switch storms between clients."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"```python\nfor attempt in range(3):\n    try:\n        sidecar.load(new_model_id)\n        break\n    except SttModelBusyError:\n        time.sleep(1.0)  # in-flight transcription on the old model\nelse:\n    return \"model busy\", 409\n```","preventionTips":["Serialize model switches and transcriptions through one coordinator/queue.","Settle on a single dictation model per session.","Return 409 with Retry-After semantics so clients back off politely."],"tags":["stt","busy","model-switch","concurrency"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}