{"record":{"id":"34891fee392fb219","repo":"BerriAI/litellm","slug":"invalid-response-format-received-response-does-no-34891f","errorCode":null,"errorMessage":"Invalid response format. Received response does not match the expected format. Got: ","messagePattern":"Invalid response format\\. Received response does not match the expected format\\. Got: ","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/watsonx/audio_transcription/transformation.py","lineNumber":188,"sourceCode":"        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            )\n\n        response: Final = TranscriptionResponse(**response_kwargs)\n\n        # Add other fields using dictionary-style assignment (like duration, task, etc.)\n        # Skip fields that TranscriptionResponse doesn't accept in __init__()\n        for key, value in raw_response_json.items():\n            if key not in [\n                \"text\",\n                \"usage\",\n                \"model\",\n            ]:  # text/usage already set, model should be excluded\n                response[key] = value\n\n        return response\n","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/watsonx/audio_transcription/transformation.py#L170-L206","documentation":"After parsing, the WatsonX transcription transformer keeps only 'text' and 'usage' from the response JSON. If neither key is present, response_kwargs is empty and this ValueError fires. Quirk to know while debugging: the raise passes two arguments (message string, raw_response_json), so str(e) renders as a tuple and the 'Got: ' part of the printed message always looks empty - the actual payload is the second tuple element. An error payload like {\"error\": ...} with status 200 or an unexpected schema triggers it.","triggerScenarios":"WatsonX returns a JSON error body (missing/invalid fields) with status 200; endpoint version drift returning e.g. {\"results\": ...} instead of {\"text\": ...}; empty JSON {} from a gateway; responses where the transcription text key was renamed.","commonSituations":"Migrating between WatsonX speech API versions; custom api_base gateways rewrapping payloads; silent quota/auth errors delivered as 200 with an error JSON.","solutions":["Inspect e.args[-1] (the second ValueError argument) - it holds the raw response dict that failed the shape check.","Verify the model and endpoint actually correspond to WatsonX speech-to-text; wrong endpoints return other shapes.","Print the payload once via litellm.set_verbose = True to see the real keys returned.","Pin/upgrade litellm if WatsonX changed its transcription response schema."],"exampleFix":"# before\ntry:\n    resp = litellm.transcription(model=\"watsonx/whisper-large-v3\", file=f)\nexcept ValueError as e:\n    print(str(e))  # confusing tuple output, 'Got: ' looks empty\n\n# after\ntry:\n    resp = litellm.transcription(model=\"watsonx/whisper-large-v3\", file=f)\nexcept ValueError as e:\n    raw = e.args[-1] if len(e.args) > 1 else None  # actual response dict\n    logging.error(\"unexpected watsonx transcription payload: %r\", raw)\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 \"Invalid response format\" in str(e):\n        raw = e.args[-1] if len(e.args) > 1 else None  # actual response dict (2-arg raise quirk)\n        logging.error(\"unexpected watsonx payload: %r\", raw)\n        raise UpstreamContractError(\"watsonx transcription schema mismatch\") from e\n    raise","preventionTips":["Remember the two-arg ValueError: the real payload is in e.args[-1], not in the message text.","Pin litellm and WatsonX speech API versions you tested together.","Log full payloads (sampled) in staging to detect schema drift early."],"tags":["watsonx","audio-transcription","response-schema","response-parsing","litellm"],"backgroundTag":"unexpected-response-schema","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}