Skip to content

fix(openai): guard against choices=None in streamed chunks (#5165)#5170

Merged
DouweM merged 1 commit intomainfrom
openai-chunk-choices
Apr 23, 2026
Merged

fix(openai): guard against choices=None in streamed chunks (#5165)#5170
DouweM merged 1 commit intomainfrom
openai-chunk-choices

Conversation

@adtyavrdhn
Copy link
Copy Markdown
Member

OpenAI-compatible providers can emit malformed chunks with choices: null; the openai SDK's loose constructor passes them through as typed objects despite the declared List[Choice]. Replace the IndexError guard with a truthiness check that covers both None and the documented empty-list final usage chunk, matching the existing delta is None precedent.

Checklist

  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • No breaking changes in accordance with the version policy.
  • PR title is fit for the release changelog.

OpenAI-compatible providers can emit malformed chunks with `choices: null`;
the openai SDK's loose constructor passes them through as typed objects
despite the declared `List[Choice]`. Replace the `IndexError` guard with a
truthiness check that covers both `None` and the documented empty-list
final usage chunk, matching the existing `delta is None` precedent.
@github-actions github-actions Bot added size: S Small PR (≤100 weighted lines) bug Report that something isn't working, or PR implementing a fix labels Apr 23, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment on lines +2646 to +2648
if not chunk.choices:
continue
choice = chunk.choices[0]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Other model adapters still use the old try/except IndexError pattern

The huggingface (pydantic_ai_slim/pydantic_ai/models/huggingface.py:500-503), groq (pydantic_ai_slim/pydantic_ai/models/groq.py:601-604), and mistral (pydantic_ai_slim/pydantic_ai/models/mistral.py:679-682) adapters still use try: chunk.choices[0] / except IndexError: continue. If those providers can also emit choices=None, they would crash with a TypeError rather than gracefully skipping. This isn't a bug in this PR (which is scoped to OpenAI), but if the intent is to harden against malformed SDK objects in general, the same fix should be applied to those adapters for consistency.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah might as well

Copy link
Copy Markdown
Collaborator

@DouweM DouweM Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather merge it as is now, as the others don't have any misbehaving supposedly compatible APIs.

@github-actions
Copy link
Copy Markdown
Contributor

@DouweM DouweM merged commit 44622b0 into main Apr 23, 2026
67 checks passed
@DouweM DouweM deleted the openai-chunk-choices branch April 23, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Report that something isn't working, or PR implementing a fix size: S Small PR (≤100 weighted lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAI streaming iterator crashes when streamed chunk has choices=None

2 participants