diff --git a/src/openai/lib/_parsing/_responses.py b/src/openai/lib/_parsing/_responses.py index 232718cef6..5a1b76c4c6 100644 --- a/src/openai/lib/_parsing/_responses.py +++ b/src/openai/lib/_parsing/_responses.py @@ -58,7 +58,10 @@ def parse_response( ) -> ParsedResponse[TextFormatT]: output_list: List[ParsedResponseOutputItem[TextFormatT]] = [] - for output in response.output: + # `response.output` can be None for incomplete/failed/reasoning-only + # responses (and via some proxy/aggregator backends); guard so the stream + # parser yields an empty output instead of raising TypeError. + for output in (response.output or []): if output.type == "message": content_list: List[ParsedContent[TextFormatT]] = [] for item in output.content: diff --git a/tests/lib/responses/test_parse_response_none_output.py b/tests/lib/responses/test_parse_response_none_output.py new file mode 100644 index 0000000000..def3255847 --- /dev/null +++ b/tests/lib/responses/test_parse_response_none_output.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from openai._types import omit +from openai.lib._parsing._responses import parse_response +from openai.types.responses import Response + + +def _minimal_response(**overrides: object) -> Response: + # Build a Response with the required scalar fields set; `output` is the + # field under test. Uses construct() to avoid pulling a full live payload. + base: dict[str, object] = dict( + id="resp_test", + created_at=0.0, + error=None, + incomplete_details=None, + instructions=None, + metadata=None, + model="gpt-4o-mini", + object="response", + output=[], + parallel_tool_calls=True, + temperature=1.0, + tool_choice="auto", + tools=[], + top_p=1.0, + ) + base.update(overrides) + return Response.construct(**base) + + +def test_parse_response_handles_none_output() -> None: + # `output` can be None for incomplete/failed/reasoning-only responses and + # via some proxy/aggregator backends. parse_response must not raise + # TypeError('NoneType' object is not iterable) — it should yield empty output. + response = _minimal_response(output=None) + + parsed = parse_response(text_format=omit, input_tools=None, response=response) + + assert parsed.output == []