fix: handle empty string finish_reason in API responses - #20732
Closed
0xnxxh wants to merge 1 commit into
Closed
Conversation
Some OpenAI-compatible API providers (e.g., packyapi) return an empty string "" for the finish_reason field instead of a valid value like "stop". This causes pydantic validation errors when litellm tries to parse the response. This fix changes the condition from `if finish_reason is None:` to `if not finish_reason:` to handle both None and empty string cases, defaulting to "stop" when finish_reason is falsy. Fixes the following error: pydantic_core._pydantic_core.ValidationError: 1 validation error for Choices finish_reason Input should be 'stop', 'content_filter', 'function_call', 'tool_calls', 'length', 'guardrail_intervened', 'eos', 'finish_reason_unspecified' or 'malformed_function_call'
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Greptile OverviewGreptile SummaryChanged
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py | Changed finish_reason check from is None to not finish_reason to handle empty strings, but two other similar patterns in the file need the same fix |
Sequence Diagram
sequenceDiagram
participant Provider as API Provider
participant LiteLLM as LiteLLM
participant Parser as convert_to_model_response_object
participant Validator as Pydantic Model
Provider->>LiteLLM: API Response with finish_reason=""
LiteLLM->>Parser: response_object
Parser->>Parser: choice.get("finish_reason", None)
Note over Parser: Returns "" (empty string)
Parser->>Parser: if not finish_reason
Note over Parser: Evaluates to True (empty string is falsy)
Parser->>Parser: finish_reason = "stop"
Parser->>Validator: Choices(finish_reason="stop", ...)
Validator->>LiteLLM: Valid ModelResponse
LiteLLM->>Provider: Success
Contributor
Additional Comments (2)
|
This was referenced Mar 3, 2026
Contributor
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Some OpenAI-compatible API providers (e.g., packyapi) return an empty string
""for thefinish_reasonfield instead of a valid value like"stop". This causes pydantic validation errors when litellm tries to parse the response.Error
Solution
Changed the condition from
if finish_reason is None:toif not finish_reason:inconvert_dict_to_response.pyto handle bothNoneand empty string cases, defaulting to"stop"whenfinish_reasonis falsy.Testing
Tested with packyapi which returns empty string for
finish_reason. After this fix, the response is parsed successfully withfinish_reasondefaulting to"stop".Changes
litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.pyline 591if finish_reason is None:toif not finish_reason: # Handle both None and empty stringThis is a minimal, backward-compatible fix that improves compatibility with OpenAI-compatible API providers that don't strictly follow the spec.