{"record":{"id":"91623ae8e610d9ea","repo":"unslothai/unsloth","slug":"audio-generation-cancelled-91623a","errorCode":null,"errorMessage":"Audio generation cancelled","messagePattern":"Audio generation cancelled","errorType":"exception","errorClass":"AudioGenerationCancelledError","httpStatus":null,"severity":"info","filePath":"studio/backend/core/inference/orchestrator.py","lineNumber":2126,"sourceCode":"        Blocking — sends command and waits for the full audio response.\n        \"\"\"\n        if not self._ensure_subprocess_alive():\n            raise RuntimeError(\"Inference subprocess is not running\")\n        if not self.active_model_name:\n            raise RuntimeError(\"No active model\")\n        expected_model = self.active_model_name\n\n        # Serialize under _gen_lock and reserve dispatcher admission before waiting for\n        # compare work to drain. A bare idle wait is racy: a compare request can register\n        # between the wait and this command, leaving TTS queued without safe ownership of\n        # the worker's single shared cancel event.\n        with self._gen_lock:\n            with self._dispatcher_lifecycle_lock:\n                self._exclusive_tts_pending = True\n            try:\n                dispatcher_idle = self._wait_dispatcher_idle(cancel_event = cancel_event)\n                if cancel_event is not None and cancel_event.is_set():\n                    raise AudioGenerationCancelledError(\"Audio generation cancelled\")\n                if not dispatcher_idle:\n                    raise RuntimeError(\n                        \"Cannot start audio generation while compare requests are active\"\n                    )\n\n                # Recheck after the dispatcher wait: unload can set its flag without\n                # _gen_lock, and a switch may have completed while this call was queued.\n                if self._unload_pending or self.active_model_name != expected_model:\n                    raise AudioGenerationCancelledError(\"model is being unloaded\")\n\n                # Bound public API integers before either enqueuing work or\n                # calculating the floating-point watchdog deadline.\n                max_new_tokens = min(\n                    AUDIO_GENERATION_MAX_TOKENS,\n                    max(1, int(max_new_tokens)),\n                )\n                generation_timeout = _audio_generation_timeout(max_new_tokens)\n                request_id = str(uuid.uuid4())","sourceCodeStart":2108,"sourceCodeEnd":2144,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/orchestrator.py#L2108-L2144","documentation":"AudioGenerationCancelledError raised at admission time: the caller's cancel_event became set while the request waited for the dispatcher (compare requests) to go idle under _gen_lock. The request never reached the worker; this is a clean, cooperative cancellation before work started.","triggerScenarios":"Caller sets cancel_event (user pressed stop, request aborted, unload triggered) while compare/generation traffic keeps the dispatcher busy and generate_audio is still parked in _wait_dispatcher_idle.","commonSituations":"User cancels TTS playback while comparisons are running; HTTP client disconnects and the server cancels the pending audio task; UI unload racing an in-flight TTS request.","solutions":["Treat as normal cancellation — do not show it as an error to the user.","If cancellation was unexpected, check what set cancel_event (client disconnect, unload flow).","Retry the request if audio is still wanted and the model remains loaded."],"exampleFix":"// before\nwav, sr = orchestrator.generate_audio(text)\n// after\ntry:\n    wav, sr = orchestrator.generate_audio(text)\nexcept AudioGenerationCancelledError:\n    return  # user cancelled — not an error","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    wav, sr = orchestrator.generate_audio(text, cancel_event=ev)\nexcept AudioGenerationCancelledError:\n    return None  # admission-time cancel: nothing ran, nothing to clean up","preventionTips":["Don't set cancel_event until you actually intend to abandon the result.","Cancel at admission is free — no worker work has started."],"tags":["inference","tts","cancellation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}