Repository navigation
fix(responses): guard parser/output_text when response.output is null - #3323
jackpalm88 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 946947ce15
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| """ | ||
| texts: List[str] = [] | ||
| for output in self.output: | ||
| for output in (self.output or []): |
There was a problem hiding this comment.
Make
output nullable for strict validation
When the API returns output: null and the client is configured with _strict_response_validation=True, this guard is never reached: _process_response_data calls validate_type() before constructing the Response, and Response.output is still declared as List[ResponseOutputItem], so Pydantic rejects None up front. This means strict-validation users still get an APIResponseValidationError for the null-output response this change is trying to tolerate; the field type needs to allow None as well as the runtime guard.
Useful? React with 👍 / 👎.
|
Happy to adjust the regression tests if maintainers prefer a different test location or setup. |
|
AI-assisted independent offline check at
If only JSON null is intended to be recoverable, Scope: six fictional constructed cases, actual helpers, Python3.14/Pydantic2.13.5 and shared local dependencies with archived sources. No provider responses, streaming or full SDK suite; network denied. This is not evidence that the provider emits False,0 or null nested content. Standalone reproducerimport json
from openai.types.responses import Response,ResponseOutputMessage,ResponseOutputText
from openai.lib._parsing._responses import parse_response
from openai import omit
rows=[]
message=ResponseOutputMessage.construct(type='message',id='fictional_msg',role='assistant',status='completed',content=[ResponseOutputText.construct(type='output_text',text='hello',annotations=[])])
for label,out in [('null',None),('empty',[]),('message',[message]),('false',False),('zero',0),('missing_content',[ResponseOutputMessage.construct(type='message',id='fictional',role='assistant',status='completed',content=None)])]:
response=Response.construct(id='fictional_response',object='response',created_at=0,model='fictional_model',output=out,status='incomplete',metadata={'fictional':'retained'},incomplete_details={'reason':'max_output_tokens'})
row={'case':label}
try:row['output_text']=response.output_text
except Exception as e:row['text_error']=type(e).__name__
try:
parsed=parse_response(response=response,text_format=omit,input_tools=[])
row.update(parsed_count=len(parsed.output),status=parsed.status,metadata=parsed.metadata)
except Exception as e:row['parse_error']=type(e).__name__
rows.append(row)
print(json.dumps(rows)) |
Fix parse_response crash when
response.outputisNoneSummary
This patch hardens the OpenAI Python SDK Responses parsing path against
output=Nonepayloads.Observed failure (openai==2.33.0):
openai/lib/_parsing/_responses.pyiteratesresponse.outputunconditionally.output: null, parser raises:TypeError: 'NoneType' object is not iterablePatch behavior:
response.output is Noneas an empty list in parser loop.Response.output_textproperty for consistency.Why
In rare edge cases, a Responses payload may contain
output: null; the SDK should handle this defensively.Changes
src/openai/lib/_parsing/_responses.pysrc/openai/types/responses/response.pyExpected result
parse_response(...)no longer crashes whenresponse.output is None.Response.output_textreturns""instead of crashing whenself.output is None.Suggested tests
Response.model_construct(..., output=None)is passed toparse_response.output=[].Response(..., output=None).output_text == "".