{"record":{"id":"fdaa2454d7e27719","repo":"BerriAI/litellm","slug":"raw-response-text-fdaa24","errorCode":null,"errorMessage":"raw_response.text","messagePattern":"raw_response\\.text","errorType":"http","errorClass":"OVHCloudException","httpStatus":null,"severity":"error","filePath":"litellm/llms/ovhcloud/audio_transcription/transformation.py","lineNumber":142,"sourceCode":"                processed_audio.filename,\n                processed_audio.file_content,\n                processed_audio.content_type,\n            )\n        }\n\n        return AudioTranscriptionRequestData(data=form_fields, files=files)\n\n    def transform_audio_transcription_response(\n        self,\n        raw_response: httpx.Response,\n    ) -> TranscriptionResponse:\n        \"\"\"\n        Transform OVHCloud audio transcription response to OpenAI-compatible TranscriptionResponse.\n        \"\"\"\n        try:\n            response_json: Final = raw_response.json()\n        except Exception:\n            raise OVHCloudException(\n                message=raw_response.text,\n                status_code=raw_response.status_code,\n                headers=raw_response.headers,\n            )\n\n        text: Final = response_json.get(\"text\") or response_json.get(\"transcript\") or \"\"\n        response: Final = TranscriptionResponse(text=text)\n\n        # OVHCloud field migration (deadline: 2026-05-11):\n        # `duration` is replaced by `seconds` in STT responses.\n        # Prefer `seconds`, fall back to `duration`, normalize to `duration`\n        # so downstream consumers see a consistent key.\n        duration: Final = (\n            response_json[\"seconds\"]\n            if \"seconds\" in response_json and response_json[\"seconds\"] is not None\n            else response_json.get(\"duration\")\n        )\n        if duration is not None:","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/ovhcloud/audio_transcription/transformation.py#L124-L160","documentation":"LiteLLM's OVHCloud audio-transcription handler calls raw_response.json(); if the OVHCloud AI Endpoints body is not JSON, it raises OVHCloudException whose message is the raw response body text, carrying the real HTTP status code and headers. The raw text usually states the actual problem (auth, model access, gateway error).","triggerScenarios":"Calling litellm.transcription() with an ovhcloud/* model when the endpoint replies with HTML or plain text: invalid/expired token producing an error page, model not deployed on the OVH project, or gateway maintenance pages.","commonSituations":"OVH AI Endpoints token missing or wrong; requesting a whisper/stt model that is not enabled for the project; OVH gateway incidents returning HTML.","solutions":["Read the exception message - it contains the raw body, which names the real failure","Verify the OVH token and that the model is deployed/enabled on your OVH AI Endpoints project","Match the model string exactly to OVH's documentation","Retry later if the body shows a transient gateway error"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Catch OVHCloudException around litellm.transcription(); the message IS the raw body, so log it verbatim - it names the actual OVH problem (token, model access, gateway). Retry only when the body indicates a transient error.","preventionTips":["Validate the OVH token and deployed model list at integration time","Log exception bodies verbatim - they are the provider's own error text","Wrap transcription flows with a fallback provider for resilience"],"tags":["ovhcloud","audio-transcription","json-parsing","http-response","litellm"],"backgroundTag":"invalid-json-response","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}