fix: guard against empty/filtered LLM responses in get_first_message_content#524
fix: guard against empty/filtered LLM responses in get_first_message_content#524qizwiz wants to merge 1 commit into
Conversation
…content Add null checks in openai_client.py and azureai_client.py before accessing choices[0].message.content. Empty choices causes IndexError; None message (some providers on filtered content with HTTP 200) causes AttributeError.
There was a problem hiding this comment.
Code Review
This pull request introduces validation checks in the get_first_message_content function for both Azure and OpenAI clients to handle empty or null responses from the LLM. The reviewer recommended extending these checks to include a validation for message.content being None. This ensures the function consistently returns a string as per its type hint, preventing potential errors when responses are filtered or contain non-textual data.
| if not completion.choices or completion.choices[0].message is None: | ||
| raise ValueError("LLM returned empty or filtered response") |
There was a problem hiding this comment.
The check should also include a validation for completion.choices[0].message.content. In some scenarios (such as content filtering or when the model returns a tool call instead of text), the message object might exist but its content field can be None. Since this function is type-hinted to return a str, returning None would violate the contract and likely cause errors in downstream components that expect a string. Adding this check ensures that we only proceed when actual text content is available.
| if not completion.choices or completion.choices[0].message is None: | |
| raise ValueError("LLM returned empty or filtered response") | |
| if not completion.choices or completion.choices[0].message is None or completion.choices[0].message.content is None: | |
| raise ValueError("LLM returned empty or filtered response") |
| if not completion.choices or completion.choices[0].message is None: | ||
| raise ValueError("LLM returned empty or filtered response") |
There was a problem hiding this comment.
Similar to the Azure client, the check here should also validate that completion.choices[0].message.content is not None. This prevents the function from returning None when a str is expected, which can happen if the response is filtered or contains non-textual data. This is especially important given the PR's goal of guarding against "filtered" responses.
| if not completion.choices or completion.choices[0].message is None: | |
| raise ValueError("LLM returned empty or filtered response") | |
| if not completion.choices or completion.choices[0].message is None or completion.choices[0].message.content is None: | |
| raise ValueError("LLM returned empty or filtered response") |
What
Add null checks in
api/openai_client.pyandapi/azureai_client.pybefore accessingchoices[0].message.contentinget_first_message_content.Why
Two crash vectors exist:
IndexError— whenchoicesis empty (network interruption, provider edge cases returning HTTP 200 with empty body)AttributeError— whenchoices[0].messageisNone. Observed on Gemini via OpenAI-compatible endpoint on PROHIBITED_CONTENT (HTTP 200 withmessage: null)Fix
No behaviour change for well-formed responses.