{"record":{"id":"dc5add84e88548e2","repo":"BerriAI/litellm","slug":"error-transforming-response-to-json-e-nresponse","errorCode":null,"errorMessage":"Error transforming response to json: {e}\\nResponse: {raw_response.text}","messagePattern":"Error transforming response to json: (.+?)\\\\nResponse: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/watsonx/audio_transcription/transformation.py","lineNumber":173,"sourceCode":"        api_version: Final = optional_params.get(\"api_version\", None) or litellm.WATSONX_DEFAULT_API_VERSION\n        url = f\"{url}?version={api_version}\"\n\n        return url\n\n    def transform_audio_transcription_response(\n        self,\n        raw_response: Response,\n    ) -> TranscriptionResponse:\n        \"\"\"\n        Transform the audio transcription response from WatsonX.\n\n        WatsonX may include a 'model' field in the response, which needs to be\n        removed before creating the TranscriptionResponse object.\n        \"\"\"\n        try:\n            raw_response_json: Final = raw_response.json()\n        except Exception as e:\n            raise ValueError(f\"Error transforming response to json: {e}\\nResponse: {raw_response.text}\")\n\n        # Extract only valid fields for TranscriptionResponse.__init__()\n        # TranscriptionResponse only accepts 'text' and 'usage' in __init__()\n        text: Final = raw_response_json.get(\"text\")\n        usage: Final = raw_response_json.get(\"usage\")\n\n        # Create response with only valid fields\n        response_kwargs: Final = {}\n        if text is not None:\n            response_kwargs[\"text\"] = text\n        if usage is not None:\n            response_kwargs[\"usage\"] = usage\n\n        if not response_kwargs:\n            raise ValueError(\n                \"Invalid response format. Received response does not match the expected format. Got: \",\n                raw_response_json,\n            )","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/watsonx/audio_transcription/transformation.py#L155-L191","documentation":"WatsonX audio transcription transformation calls raw_response.json() to convert the provider response; if the body is not parseable JSON (HTML error page, empty body, SSE/text), this ValueError wraps the parse error and includes the raw text for inspection. Nothing is validated about the status code first, so non-2xx text bodies also surface here.","triggerScenarios":"litellm.transcription(model=\"watsonx/...\", file=...) where the WatsonX endpoint replies with a non-JSON error (auth HTML, WAF page); an incorrect api_base/region URL; truncated responses on large audio uploads.","commonSituations":"IBM Cloud endpoints behind SSO proxies that redirect unauthenticated requests to login pages; wrong WATSONX_REGION value; network appliances truncating large multipart uploads; debugging with verbose off.","solutions":["Read the Response: text appended to the exception - it shows exactly what came back.","Confirm api_base/region and credentials (WATSONX_APIKEY / token) with a direct curl to the WatsonX speech endpoint.","Check HTTP proxy interference for the ibm.com host.","Retry once - truncated bodies from dropped connections are often transient."],"exampleFix":"# before (no handling)\nresp = litellm.transcription(model=\"watsonx/whisper-large-v3\", file=open(\"a.wav\", \"rb\"))\n\n# after (surface the raw body for diagnosis)\ntry:\n    resp = litellm.transcription(model=\"watsonx/whisper-large-v3\", file=open(\"a.wav\", \"rb\"))\nexcept ValueError as e:\n    logging.error(\"watsonx transcription failed: %s\", e)  # includes raw response text\n    raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.transcription(model=\"watsonx/whisper-large-v3\", file=f)\nexcept ValueError as e:\n    if \"Error transforming response to json\" in str(e):\n        raw = str(e).split(\"Response:\", 1)[-1]\n        logging.error(\"watsonx non-JSON body: %s\", raw[:500])\n        raise UpstreamResponseError(raw[:500]) from e\n    raise","preventionTips":["Verify WATSONX_API_BASE/region and credentials with a direct curl before wiring transcription.","Keep verbose logging on in staging to capture raw bodies.","Retry once on parse failures; truncated bodies are frequently transient."],"tags":["watsonx","audio-transcription","json-parse","response-parsing","litellm"],"backgroundTag":"invalid-json-response","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}