Follow-up to #3325 (fixed for output: null in #3345).
Same crash one level deeper: when the API returns a message output item with content: null, parse_response (src/openai/lib/_parsing/_responses.py) raises a raw TypeError: 'NoneType' object is not iterable instead of parsing.
Repro (both paths hit it, sync and async):
client.responses.parse(model="...", input="...")
# API returns output: [{"id": ..., "type": "message", "role": "assistant",
# "status": "completed", "content": null}]
# -> TypeError: 'NoneType' object is not iterable
This also breaks streaming when response.completed carries explicit output with a null-content message, since explicit completion output is passed straight through to parse_response.
Null reaches the parser because stream events are built without validation, and the same payload passes the non-streaming path too (verified with a mocked transport). Treating null content as empty — the same or [] idiom #3345 used for output — fixes it. PR follows.
Follow-up to #3325 (fixed for
output: nullin #3345).Same crash one level deeper: when the API returns a message output item with
content: null,parse_response(src/openai/lib/_parsing/_responses.py) raises a rawTypeError: 'NoneType' object is not iterableinstead of parsing.Repro (both paths hit it, sync and async):
This also breaks streaming when
response.completedcarries explicit output with a null-content message, since explicit completion output is passed straight through toparse_response.Null reaches the parser because stream events are built without validation, and the same payload passes the non-streaming path too (verified with a mocked transport). Treating null content as empty — the same
or []idiom #3345 used foroutput— fixes it. PR follows.