{"record":{"id":"b82f6538e3440422","repo":"ATH-MaaS/Pixelle-Video","slug":"tts-generation-failed-error-msg","errorCode":null,"errorMessage":"TTS generation failed: {error_msg}","messagePattern":"TTS generation failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/tts_service.py","lineNumber":261,"sourceCode":"            kit = await self.core._get_or_create_comfykit()\n            \n            # Determine what to pass to ComfyKit based on source\n            if workflow_info[\"source\"] == \"runninghub\" and \"workflow_id\" in workflow_info:\n                # RunningHub: pass workflow_id\n                workflow_input = workflow_info[\"workflow_id\"]\n                logger.info(f\"Executing RunningHub TTS workflow: {workflow_input}\")\n            else:\n                # Selfhost: pass file path\n                workflow_input = workflow_info[\"path\"]\n                logger.info(f\"Executing selfhost TTS workflow: {workflow_input}\")\n            \n            result = await kit.execute(workflow_input, workflow_params)\n            \n            # 4. Handle result\n            if result.status != \"completed\":\n                error_msg = result.msg or \"Unknown error\"\n                logger.error(f\"TTS generation failed: {error_msg}\")\n                raise Exception(f\"TTS generation failed: {error_msg}\")\n            \n            # ComfyKit result can have audio files in different output types\n            # Try to get audio file path from result\n            audio_path = None\n            \n            # Check for audio files in result.audios (if available)\n            if hasattr(result, 'audios') and result.audios:\n                audio_path = result.audios[0]\n                logger.debug(f\"✅ Found audio in result.audios: {audio_path}\")\n            # Check for files in result.files\n            elif hasattr(result, 'files') and result.files:\n                audio_path = result.files[0]\n                logger.debug(f\"✅ Found audio in result.files: {audio_path}\")\n            # Check in outputs dictionary\n            elif hasattr(result, 'outputs') and result.outputs:\n                logger.debug(f\"Searching for audio file in result.outputs: {result.outputs}\")\n                # Try to find audio file in outputs\n                for key, value in result.outputs.items():","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/tts_service.py#L243-L279","documentation":"TTSService._call_comfyui_workflow runs a TTS ComfyUI/RunningHub workflow via kit.execute() and requires result.status == 'completed'. Any other status raises 'TTS generation failed: {error_msg}' using result.msg from ComfyKit. It reports the TTS workflow run itself failed on the backend.","triggerScenarios":"Calling TTSService.__call__ where kit.execute(workflow_input, workflow_params) returns a non-'completed' status — backend node error in the TTS graph, invalid/missing 'text' or 'voice' parameter, unknown workflow_id, RunningHub task failure/timeout, or ComfyUI missing the TTS custom nodes.","commonSituations":"Voice id not supported by the deployed TTS node; text too long for the node's limits; selfhost ComfyUI missing the TTS custom node pack or model weights; stale RunningHub workflow_id after republishing; API key or quota problems on RunningHub.","solutions":["Read the {error_msg} suffix and logger.error output — result.msg identifies the failing backend node or reason; address that first.","Validate inputs: non-empty text, a voice id the workflow actually supports, and speed within the node's accepted range.","Verify the TTS workflow_id (RunningHub) or file path (selfhost) exists and is current.","For selfhost, confirm the TTS custom nodes and models are installed and ComfyUI logs show no import errors; for RunningHub, check API key validity and task quota.","Retry with backoff if the message indicates transient backend conditions (timeout, queue, OOM)."],"exampleFix":"// before\nif result.status != \"completed\":\n    raise Exception(f\"TTS generation failed: {result.msg}\")\n// after\nif result.status != \"completed\":\n    logger.error(f\"TTS workflow {workflow_input} failed: {result.msg}\")\n    raise TTSWorkflowError(workflow_input, result.status, result.msg)  # typed, actionable error","handlingStrategy":"try-catch","validationCode":"# before calling TTS\nassert text and text.strip(), \"text must be non-empty\"\nif len(text) > MAX_TTS_CHARS:\n    text = text[:MAX_TTS_CHARS]  # or chunk\nif voice is not None:\n    assert voice in SUPPORTED_VOICES, f\"unsupported voice: {voice}\"\nassert 0.5 <= speed <= 2.0, \"speed out of range\"\n# verify backend reachable / workflow_id valid before submit","typeGuard":"def tts_completed(result) -> bool:\n    return getattr(result, \"status\", None) == \"completed\"","tryCatchPattern":"try:\n    audio = await tts_service(...)\nexcept Exception as e:\n    if str(e).startswith(\"TTS generation failed:\"):\n        reason = str(e).removeprefix(\"TTS generation failed: \")\n        logger.warning(\"tts workflow failed: %s\", reason)\n        audio = await tts_service(...)  # retry with backoff or fallback engine\n    else:\n        raise","preventionTips":["Validate voice/speed/text against the workflow's supported values before calling.","Verify the TTS workflow_id/file is current and the backend has the required custom nodes and models.","Monitor RunningHub API key validity and quota.","Log result.msg verbatim for the real backend failure reason.","Apply retry with exponential backoff for transient statuses."],"tags":["workflow-execution","comfyui","tts","runninghub","async"],"backgroundTag":"workflow-execution-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}