{"record":{"id":"bb6a5ca96d60c7de","repo":"BerriAI/litellm","slug":"unexpected-response-type-type-raw-response","errorCode":null,"errorMessage":"Unexpected response type: {type(raw_response)}","messagePattern":"Unexpected response type: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/completion_extras/litellm_responses_transformation/transformation.py","lineNumber":744,"sourceCode":"        self,\n        model: str,\n        raw_response: \"BaseModel\",\n        model_response: \"ModelResponse\",\n        logging_obj: \"LiteLLMLoggingObj\",\n        request_data: dict,\n        messages: list[\"AllMessageValues\"],\n        optional_params: dict,\n        litellm_params: dict,\n        encoding: object,\n        api_key: str | None = None,\n        json_mode: bool | None = None,\n    ) -> \"ModelResponse\":\n        \"\"\"Transform Responses API response to chat completion response\"\"\"\n        from litellm.responses.utils import ResponseAPILoggingUtils\n        from litellm.types.llms.openai import ResponsesAPIResponse\n\n        if not isinstance(raw_response, ResponsesAPIResponse):\n            raise ValueError(f\"Unexpected response type: {type(raw_response)}\")\n\n        if raw_response.error is not None:\n            raise ValueError(f\"Error in response: {raw_response.error}\")\n\n        output_items = raw_response.output\n        if len(output_items) == 0:\n            recovered_output_items: Final = self._recover_output_items_from_logging(logging_obj)\n            if recovered_output_items:\n                output_items = cast(Any, recovered_output_items)\n                raw_response.output = cast(Any, recovered_output_items)\n                verbose_logger.warning(\n                    \"Recovered empty Responses API output from raw SSE for model=%s\",\n                    model,\n                )\n\n        # Convert response output to choices using the static helper\n        choices: Final = self._convert_response_output_to_choices(\n            output_items=output_items,","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/completion_extras/litellm_responses_transformation/transformation.py#L726-L762","documentation":"LiteLLMResponsesTransformationHandler.transform_response only accepts raw_response values that are ResponsesAPIResponse instances — the typed object the Responses API client returns. Anything else (a plain dict, ModelResponse, string, or None) violates the transformation contract and is rejected before conversion to a chat completion. This is an internal API contract check, not user input validation.","triggerScenarios":"Calling transform_response directly with a dict parsed from JSON instead of a ResponsesAPIResponse; a custom provider transformation returning the wrong type; version skew where a provider adapter changed its return type; middleware swapping the response object.","commonSituations":"Developers wiring custom providers into the responses bridge; code that re-implements parts of litellm's pipeline; partial upgrades where litellm subpackages disagree on types; tests passing fixtures of the wrong type.","solutions":["Construct a ResponsesAPIResponse(**dict_payload) before calling transform_response","Prefer the public litellm.completion path where typing is handled end to end","Add an isinstance assert in custom adapters so wrong types fail loudly at the boundary","Upgrade litellm if a provider adapter regression caused it"],"exampleFix":"// before\nfrom litellm.types.llms.openai import ResponsesAPIResponse\nmodel_response = transform_handler.transform_response(model, raw_response=data_dict, ...)  # ValueError: Unexpected response type\n\n// after\nraw = ResponsesAPIResponse(**data_dict)\nmodel_response = transform_handler.transform_response(model, raw_response=raw, ...)","handlingStrategy":"type-guard","validationCode":"from litellm.types.llms.openai import ResponsesAPIResponse\n\ndef ensure_responses_api_response(raw):\n    if isinstance(raw, dict):\n        return ResponsesAPIResponse(**raw)\n    return raw","typeGuard":"from litellm.types.llms.openai import ResponsesAPIResponse\n\ndef is_responses_api_response(obj) -> bool:\n    return isinstance(obj, ResponsesAPIResponse)","tryCatchPattern":"try:\n    model_response = handler.transform_response(model, raw_response=raw, ...)\nexcept ValueError as e:\n    if \"Unexpected response type\" in str(e):\n        raise TypeError(f\"adapter must pass ResponsesAPIResponse, got {type(raw)}\") from e\n    raise","preventionTips":["Wrap raw dicts in ResponsesAPIResponse at your adapter boundary before transform_response","Add isinstance asserts in custom provider adapters so wrong types fail at the seam","Keep litellm subpackages on one version"],"tags":["type-validation","responses-api","internal-api"],"backgroundTag":"invalid-response-type","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}