{"record":{"id":"ca659a6523ea43c7","repo":"microsoft/semantic-kernel","slug":"type-self-service-failed-to-generate-audio","errorCode":null,"errorMessage":"{type(self)} service failed to generate audio","messagePattern":"(.+?) service failed to generate audio","errorType":"exception","errorClass":"ServiceResponseException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/ai/open_ai/services/open_ai_handler.py","lineNumber":190,"sourceCode":"        except Exception as ex:\n            raise ServiceResponseException(\n                f\"{type(self)} service failed to transcribe audio\",\n                ex,\n            ) from ex\n\n    async def _send_text_to_audio_request(\n        self, settings: OpenAITextToAudioExecutionSettings\n    ) -> _legacy_response.HttpxBinaryResponseContent:\n        \"\"\"Send a request to the OpenAI text to audio endpoint.\n\n        The OpenAI API returns the content of the generated audio file.\n        \"\"\"\n        try:\n            return await self.client.audio.speech.create(\n                **settings.prepare_settings_dict(),\n            )\n        except Exception as ex:\n            raise ServiceResponseException(\n                f\"{type(self)} service failed to generate audio\",\n                ex,\n            ) from ex\n\n    def _handle_structured_output(\n        self, request_settings: OpenAIChatPromptExecutionSettings, settings: dict[str, Any]\n    ) -> None:\n        response_format = getattr(request_settings, \"response_format\", None)\n        if getattr(request_settings, \"structured_json_response\", False) and response_format:\n            # Case 1: response_format is a type and subclass of BaseModel\n            if isinstance(response_format, type) and issubclass(response_format, BaseModel):\n                settings[\"response_format\"] = type_to_response_format_param(response_format)\n            # Case 2: response_format is a type but not a subclass of BaseModel\n            elif isinstance(response_format, type):\n                generated_schema = KernelJsonSchemaBuilder.build(parameter_type=response_format, structured_output=True)\n                assert generated_schema is not None  # nosec\n                settings[\"response_format\"] = generate_structured_output_response_format_schema(\n                    name=response_format.__name__, schema=generated_schema","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/ai/open_ai/services/open_ai_handler.py#L172-L208","documentation":"Raised as ServiceResponseException in _send_text_to_audio_request when any exception occurs during client.audio.speech.create. This is the text-to-speech (TTS) path; failures include invalid model/voice parameters, text exceeding limits, content-filter rejections, or network/quota errors.","triggerScenarios":"Calling text-to-speech with unsupported voice names, invalid model id (e.g., not 'tts-1' or 'tts-1-hd'), text that triggers content filtering, response_format not supported, or network/rate-limit failures during client.audio.speech.create.","commonSituations":"Using a voice name not in OpenAI's supported set (alloy, echo, fable, onyx, nova, shimmer); very long input text exceeding the 4096-character limit; content filter on the TTS input; rate limit from high-frequency speech generation.","solutions":["Inspect ex.__cause__ for the specific API error","Verify the model id is 'tts-1' or 'tts-1-hd' and the voice is one of the supported names","Ensure input text is within the 4096-character limit","For content-filter rejections, sanitize or shorten the input text"],"exampleFix":"# before\nsettings = OpenAITextToAudioExecutionSettings(ai_model_id='tts-1', voice='custom_voice')\n# after — use a supported voice\nsettings = OpenAITextToAudioExecutionSettings(ai_model_id='tts-1', voice='alloy')","handlingStrategy":"validation","validationCode":"SUPPORTED_VOICES = {'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'}\nSUPPORTED_TTS_MODELS = {'tts-1', 'tts-1-hd'}\nif settings.ai_model_id not in SUPPORTED_TTS_MODELS:\n    raise ValueError(f'Unsupported TTS model: {settings.ai_model_id}')\nif settings.voice and settings.voice not in SUPPORTED_VOICES:\n    raise ValueError(f'Unsupported voice: {settings.voice}')\nif len(settings.input_text) > 4096:\n    raise ValueError('TTS input exceeds 4096 character limit')","typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions import ServiceResponseException\n\ntry:\n    audio = await service._send_text_to_audio_request(settings)\nexcept ServiceResponseException as e:\n    logger.error('TTS generation failed: %s', e)\n    raise","preventionTips":["Validate voice, model, and text length against the OpenAI TTS spec before calling","Cache generated audio to reduce API calls for repeated phrases"],"tags":["openai","text-to-audio","tts","catch-all"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}