{"record":{"id":"2842ec19e6d1c65e","repo":"calesthio/OpenMontage","slug":"voice-language-must-be-one-of-join-tts-lang","errorCode":null,"errorMessage":"voice_language must be one of: {', '.join(TTS_LANGUAGES)}","messagePattern":"voice_language must be one of: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/audio/kling_tts.py","lineNumber":207,"sourceCode":"            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\",\n            \"path\": \"/v1/audio/tts\",\n            \"payload\": payload,\n            \"operation\": \"text_to_speech\",\n            \"model\": \"kling-official-tts\",","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/audio/kling_tts.py#L189-L225","documentation":"Raised by kling_tts._build_request when voice_language (default 'en') is not in the module-level TTS_LANGUAGES whitelist. Kling TTS only supports a fixed set of language codes and the wrapper validates them client-side.","triggerScenarios":"Passing an unsupported code like 'jp' instead of 'ja', full names like 'english', or region-qualified codes like 'en-US' not present in TTS_LANGUAGES.","commonSituations":"Mapping ISO 639-1 codes incorrectly; copying language values from another provider's schema; case sensitivity ('EN' vs 'en' unless the whitelist normalizes).","solutions":["Use one of the codes in TTS_LANGUAGES (import it and print/join to see the exact allowed set)","Omit voice_language to get the default 'en'","Normalize user input (lowercase, map common aliases) before building inputs"],"exampleFix":"// before\ninputs = {\"text\": \"こんにちは\", \"voice_id\": vid, \"voice_language\": \"jp\"}  # raises\n\n// after\ninputs = {\"text\": \"こんにちは\", \"voice_id\": vid, \"voice_language\": \"ja\"}","handlingStrategy":"validation","validationCode":"from tools.audio.kling_tts import TTS_LANGUAGES\nlang = str(inputs.get(\"voice_language\") or \"en\")\nif lang not in TTS_LANGUAGES:\n    raise ValueError(f\"unsupported voice_language {lang!r}; allowed: {TTS_LANGUAGES}\")","typeGuard":"def is_supported_language(lang: str) -> bool:\n    return lang in TTS_LANGUAGES","tryCatchPattern":null,"preventionTips":["Use ISO 639-1 codes from TTS_LANGUAGES exactly","Omit voice_language for English","Map common aliases (jp→ja) in a normalization layer"],"tags":["kling","tts","language","validation"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}