{"record":{"id":"69cca969a5db8c00","repo":"BerriAI/litellm","slug":"model-unable-to-complete-request-raw-response","errorCode":null,"errorMessage":"{model} unable to complete request: {raw_response.incomplete_details.reason}","messagePattern":"(.+?) unable to complete request: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/completion_extras/litellm_responses_transformation/transformation.py","lineNumber":766,"sourceCode":"        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,\n            handle_raw_dict_callback=self._handle_raw_dict_response_item,\n        )\n\n        if len(choices) == 0:\n            if raw_response.incomplete_details is not None and raw_response.incomplete_details.reason is not None:\n                raise ValueError(f\"{model} unable to complete request: {raw_response.incomplete_details.reason}\")\n            else:\n                raise ValueError(f\"Unknown items in responses API response: {output_items}\")\n\n        setattr(model_response, \"choices\", choices)\n\n        model_response.model = model\n\n        setattr(\n            model_response,\n            \"usage\",\n            ResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage(raw_response.usage),\n        )\n\n        # Preserve hidden params from the ResponsesAPIResponse, especially the headers\n        # which contain important provider information like x-request-id\n        raw_response_hidden_params: Final = getattr(raw_response, \"_hidden_params\", {})\n        if raw_response_hidden_params:\n            if not hasattr(model_response, \"_hidden_params\") or model_response._hidden_params is None:","sourceCodeStart":748,"sourceCodeEnd":784,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/completion_extras/litellm_responses_transformation/transformation.py#L748-L784","documentation":"After converting the Responses API output to chat choices, zero choices were produced and raw_response.incomplete_details.reason is set. The provider is telling you it stopped early — e.g. max_output_tokens reached or a content filter fired — so the output contained no convertible message items.","triggerScenarios":"Calling with max_output_tokens set so low the model never emits a message item; safety-system refusal truncation; providers that stop before any output when filters trigger.","commonSituations":"Aggressive max_tokens limits in agent loops; content-moderation systems; long reasoning models spending the entire token budget on reasoning items.","solutions":["Raise or remove max_output_tokens so the model has budget to produce message output","Inspect raw_response.incomplete_details.reason — 'max_output_tokens' means raise the cap; filter reasons mean adjust content","For reasoning models, budget for reasoning tokens explicitly"],"exampleFix":"# before\nresp = litellm.completion(model=\"o3\", messages=msgs, max_tokens=32)\n\n# after — give the model room for reasoning + message output\nresp = litellm.completion(model=\"o3\", messages=msgs, max_tokens=4096)","handlingStrategy":"validation","validationCode":"def check_token_headroom(max_tokens: int | None, max_output_tokens: int | None) -> bool:\n    cap = max_output_tokens or max_tokens\n    return cap is None or cap >= 1024  # leave room for reasoning + message","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=m, messages=msgs, max_tokens=cap)\nexcept ValueError as e:\n    if \"unable to complete request\" in str(e) and \"max_output_tokens\" in str(e):\n        resp = litellm.completion(model=m, messages=msgs, max_tokens=cap * 4)\n    else:\n        raise","preventionTips":["Set max_tokens generously for reasoning models","Check incomplete_details.reason in responses before bridging","Watch finish_reason/usage in callbacks to catch truncation early"],"tags":["responses-api","token-limit","content-filter","transformation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}