{"record":{"id":"1d3429e1a6f67795","repo":"calesthio/OpenMontage","slug":"voice-id-is-required-for-kling-official-tts","errorCode":null,"errorMessage":"voice_id is required for Kling official TTS","messagePattern":"voice_id is required for Kling official TTS","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/audio/kling_tts.py","lineNumber":203,"sourceCode":"                **self._account_usage_result(inputs, client),\n                **self._callback_result_data(inputs, task_id),\n            },\n            artifacts=[str(path) for path in paths],\n            cost_usd=self.estimate_cost(inputs),\n            duration_seconds=round(time.time() - start, 2),\n            model=\"kling-official-tts\",\n        )\n\n    def _build_request(self, inputs: dict[str, Any]) -> dict[str, Any]:\n        text = str(inputs.get(\"text\") or \"\").strip()\n        if not text:\n            raise ValueError(\"text is required\")\n        if len(text) > 5000:\n            raise ValueError(\"text exceeds Kling TTS safety limit of 5000 characters\")\n\n        voice_id = str(inputs.get(\"voice_id\") or \"\").strip()\n        if not voice_id:\n            raise ValueError(\"voice_id is required for Kling official TTS\")\n\n        voice_language = str(inputs.get(\"voice_language\") or \"en\")\n        if voice_language not in TTS_LANGUAGES:\n            raise ValueError(f\"voice_language must be one of: {', '.join(TTS_LANGUAGES)}\")\n\n        voice_speed = float(inputs.get(\"voice_speed\", 1.0))\n        if voice_speed < TTS_SPEED_MIN or voice_speed > TTS_SPEED_MAX:\n            raise ValueError(f\"voice_speed must be between {TTS_SPEED_MIN} and {TTS_SPEED_MAX}\")\n\n        payload: dict[str, Any] = {\n            \"text\": text,\n            \"voice_id\": voice_id,\n            \"voice_language\": voice_language,\n            \"voice_speed\": voice_speed,\n        }\n        self._copy_common_task_fields(inputs, payload)\n        return {\n            \"protocol\": \"classic\",","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/audio/kling_tts.py#L185-L221","documentation":"Raised by kling_tts._build_request when voice_id is missing or whitespace-only. Unlike some TTS providers, Kling official TTS has no default voice — the voice must be chosen explicitly, so the wrapper rejects the request before any API call.","triggerScenarios":"Calling the tool without voice_id, or with voice_id: '' after stripping; configs copied from a different TTS tool that defaulted the voice.","commonSituations":"Migrating from a provider where voice was optional; voice list fetched dynamically and the fetch returned nothing; config key typo (voice vs voice_id).","solutions":["Pass a valid Kling voice_id in inputs","Fetch the official voice list first and have the user/pipeline pick one","Validate inputs against the tool's required schema before dispatch"],"exampleFix":"// before\ninputs = {\"text\": \"hi\"}  # no voice_id\n\n// after\ninputs = {\"text\": \"hi\", \"voice_id\": \"your-voice-id\"}","handlingStrategy":"validation","validationCode":"if not str(inputs.get(\"voice_id\") or \"\").strip():\n    raise ValueError(\"voice_id is required; fetch the Kling voice list first\")","typeGuard":"def has_voice_id(inputs: dict) -> bool:\n    return bool(str(inputs.get(\"voice_id\") or \"\").strip())","tryCatchPattern":null,"preventionTips":["Kling has no default voice — always resolve one explicitly","Cache the fetched voice list and reference entries by id","Check the exact key name voice_id in config files"],"tags":["kling","tts","voice-id","validation"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}