BerriAI/litellm · error · ValueError
Unknown items in responses API response: {output_items}
Error message
Unknown items in responses API response: {output_items} What it means
Zero chat choices were produced from the Responses API output and there is no incomplete_details to explain why — the output array contained only item types the converter does not map to choices (e.g. only reasoning, web_search, file_search, or unknown item types, with no message/function_call). The error text dumps the unrecognized output items.
Source
Thrown at litellm/completion_extras/litellm_responses_transformation/transformation.py:768
if recovered_output_items:
output_items = cast(Any, recovered_output_items)
raw_response.output = cast(Any, recovered_output_items)
verbose_logger.warning(
"Recovered empty Responses API output from raw SSE for model=%s",
model,
)
# Convert response output to choices using the static helper
choices: Final = self._convert_response_output_to_choices(
output_items=output_items,
handle_raw_dict_callback=self._handle_raw_dict_response_item,
)
if len(choices) == 0:
if raw_response.incomplete_details is not None and raw_response.incomplete_details.reason is not None:
raise ValueError(f"{model} unable to complete request: {raw_response.incomplete_details.reason}")
else:
raise ValueError(f"Unknown items in responses API response: {output_items}")
setattr(model_response, "choices", choices)
model_response.model = model
setattr(
model_response,
"usage",
ResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage(raw_response.usage),
)
# Preserve hidden params from the ResponsesAPIResponse, especially the headers
# which contain important provider information like x-request-id
raw_response_hidden_params: Final = getattr(raw_response, "_hidden_params", {})
if raw_response_hidden_params:
if not hasattr(model_response, "_hidden_params") or model_response._hidden_params is None:
model_response._hidden_params = {}
# Merge the raw_response hidden params with model_response hidden paramsView on GitHub (pinned to 6c2dcb801b)
Solutions
- Upgrade litellm — new output item types are added as providers ship them
- Inspect the dumped output_items in the message to identify which item type is unmapped
- If a proxy is involved, check it forwards the response.completed event with the full output
- Capture the raw response (via callbacks) and report unmapped item types to litellm
Defensive patterns
Strategy: try-catch
Validate before calling
def output_has convertible_items(parsed) -> bool:
types = {item.get("type") for item in (parsed.output or [])}
return bool(types & {"message", "function_call", "custom_tool_call"}) Try / catch
try:
resp = litellm.completion(**kwargs)
except ValueError as e:
if "Unknown items in responses API response" in str(e):
log_unmapped_output(e) # capture item types, file upstream
raise Prevention
- Keep litellm current so new Responses output item types are mapped
- Log the dumped output_items when this fires to identify the unmapped type
- Pin provider API versions in tests to catch new item types early
When it happens
Trigger: A response whose output is exclusively non-message items (pure reasoning items with no final message, tool-only responses from non-standard providers, or new item types the installed litellm version does not recognize).
Common situations: Providers adding new Responses API output item types after your litellm version was released; reasoning models whose final message is dropped by a proxy; empty output after SSE recovery failed.
Related errors
- tool call not supported: {tool_call}
- Unexpected response type: {type(raw_response)}
- {model} unable to complete request: {raw_response.incomplete
- Unexpected responses stream payload
- Stream ended without a completed response
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/dafe1c53619ab67f.
Report an issue: GitHub.