{"record":{"id":"461e7fb4331b3d9b","repo":"BerriAI/litellm","slug":"runwayml-tts-response-missing-audio-url-in-output","errorCode":null,"errorMessage":"RunwayML TTS response missing audio URL in output","messagePattern":"RunwayML TTS response missing audio URL in output","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/runwayml/text_to_speech/transformation.py","lineNumber":493,"sourceCode":"        }\n\n        # Poll until task completes\n        polled_response: Final = self._poll_task_sync(\n            task_id=task_id,\n            api_base=self.DEFAULT_BASE_URL,\n            headers=poll_headers,\n            timeout_secs=RUNWAYML_POLLING_TIMEOUT,\n        )\n\n        # Get the completed task data\n        task_data: Final = polled_response.json()\n\n        verbose_logger.debug(\"RunwayML TTS polling complete, downloading audio\")\n\n        # Get audio URL from output\n        output: Final = task_data.get(\"output\", [])\n        if not output or not isinstance(output, list) or len(output) == 0:\n            raise ValueError(\"RunwayML TTS response missing audio URL in output\")\n\n        audio_url: Final = output[0]\n        if not isinstance(audio_url, str):\n            raise ValueError(f\"RunwayML TTS audio URL is not a string: {audio_url}\")\n\n        # Download the audio file\n        from litellm.llms.custom_httpx.http_handler import _get_httpx_client\n\n        client: Final = _get_httpx_client()\n        audio_response: Final = client.get(url=audio_url)\n        audio_response.raise_for_status()\n\n        verbose_logger.debug(\"RunwayML TTS audio downloaded successfully\")\n\n        # Return the audio data wrapped in HttpxBinaryResponseContent\n        return HttpxBinaryResponseContent(audio_response)\n\n    async def async_transform_text_to_speech_response(","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/runwayml/text_to_speech/transformation.py#L475-L511","documentation":"Contract guard after RunwayML TTS polling completes: the finished task's 'output' field is empty or not a non-empty list, so there is no audio URL to download; raised instead of returning an empty audio result.","triggerScenarios":"Triggered when the RunwayML TTS task output does not contain an audio URL.","commonSituations":"See trigger scenarios.","solutions":["The completed task output had no audio URL; inspect the task output payload.","Report to litellm issue tracker if the RunwayML output schema changed."],"exampleFix":"# fetch the task directly from RunwayML and check its output field.","handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}