{"record":{"id":"d977f4a38928ca58","repo":"unslothai/unsloth","slug":"audio-generation-cancelled","errorCode":null,"errorMessage":"Audio generation cancelled","messagePattern":"Audio generation cancelled","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"info","filePath":"studio/backend/core/inference/inference.py","lineNumber":2079,"sourceCode":"        \"\"\"\n        if not self.active_model_name:\n            raise RuntimeError(\"No active model\")\n\n        model_info = self.models[self.active_model_name]\n        audio_type = model_info.get(\"audio_type\")\n        model = model_info[\"model\"]\n        tokenizer = model_info.get(\"tokenizer\")\n\n        if not audio_type:\n            raise RuntimeError(f\"Model {self.active_model_name} is not an audio model\")\n\n        top_k = self._normalize_top_k(top_k)\n        # Every codec below concatenates its prompt instead of templating it, so this\n        # is the one choke point for all four (#7066).\n        text = neutralize_tts_prompt_text(text, audio_type)\n\n        if cancel_event is not None and cancel_event.is_set():\n            raise RuntimeError(\"Audio generation cancelled\")\n        with self._generation_lock:\n            if cancel_event is not None and cancel_event.is_set():\n                raise RuntimeError(\"Audio generation cancelled\")\n            if use_adapter is not None:\n                self._apply_adapter_state(use_adapter)\n            stopping_criteria = self._cancel_stopping_criteria(cancel_event)\n\n            if audio_type == \"snac\":\n                result = self._generate_snac(\n                    model,\n                    tokenizer,\n                    text,\n                    temperature,\n                    top_p,\n                    max_new_tokens,\n                    repetition_penalty,\n                    stopping_criteria = stopping_criteria,\n                    cancel_event = cancel_event,","sourceCodeStart":2061,"sourceCodeEnd":2097,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/inference.py#L2061-L2097","documentation":"First of three cancellation checkpoints in generate_audio: before acquiring the generation lock, the routine checks cancel_event and raises RuntimeError('Audio generation cancelled'). This gives cancellation a fast exit before prompt-neutralization and codec work, using the same sentinel message as the in-lock and post-generation checks.","triggerScenarios":"Client sets the cancel event (stop button / request abort) while the audio request is queued or just entering generate_audio, before the generation lock is acquired.","commonSituations":"User cancels a long TTS job immediately; deduplication logic cancelling superseded requests; client disconnect handlers flipping the event.","solutions":["Handle this as normal cancellation (return 'cancelled' status), not an error","If unexpected, find who shares/sets this cancel_event (watchdog, sibling request)","Do not auto-retry; re-issue the TTS request if the user still wants the audio"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if cancel_event is not None and cancel_event.is_set():\n    return {\"status\": \"cancelled\"}  # skip the call entirely","typeGuard":null,"tryCatchPattern":"try:\n    wav, sr = engine.generate_audio(text, cancel_event=ev)\nexcept RuntimeError as e:\n    if str(e) == \"Audio generation cancelled\":\n        return {\"status\": \"cancelled\"}\n    raise","preventionTips":["Check the cancel event before starting TTS work","Map the sentinel message to a 'cancelled' status, not an error","Use a fresh cancel_event per request to avoid cross-talk"],"tags":["cancellation","tts","audio","control-flow"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}