fix(openai): guard against choices=None in streamed chunks (#5165)#5170
fix(openai): guard against choices=None in streamed chunks (#5165)#5170
choices=None in streamed chunks (#5165)#5170Conversation
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.
| if not chunk.choices: | ||
| continue | ||
| choice = chunk.choices[0] |
There was a problem hiding this comment.
🚩 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
I'd rather merge it as is now, as the others don't have any misbehaving supposedly compatible APIs.
Docs Preview
|
OpenAI-compatible providers can emit malformed chunks with
choices: null; the openai SDK's loose constructor passes them through as typed objects despite the declaredList[Choice]. Replace theIndexErrorguard with a truthiness check that covers bothNoneand the documented empty-list final usage chunk, matching the existingdelta is Noneprecedent.Checklist