fix(openai_like/utils): normalize extra_body=None to {} to prevent TypeError - #21895
fix(openai_like/utils): normalize extra_body=None to {} to prevent TypeError#21895WhoisMonesh wants to merge 10 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| litellm/llms/openai_like/chat/handler.py | Adds or {} guard after optional_params.pop("extra_body", {}) to handle explicit None. Change is correct and minimal. |
| litellm/utils.py | Adds or {} normalization for extra_body from passed_params and uses .get() or {} for optional_params["extra_body"]. Both fixes are correct; minor redundancy with the existing setdefault call. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["User calls litellm.responses(..., extra_body=None)"] --> B["add_provider_specific_params_to_optional_params()"]
B --> C{"extra_body = passed_params.pop('extra_body', {})"}
C -->|"extra_body=None stored"| D{"or {} normalizes to dict"}
D --> E["extra_body = {}"]
E --> F["Merge into optional_params['extra_body']"]
F --> G["optional_params.get('extra_body') or {}"]
G --> H["Safe dict unpacking: **extra_body"]
A --> I["OpenAILikeChatHandler.completion()"]
I --> J{"extra_body = optional_params.pop('extra_body', {})"}
J -->|"extra_body=None stored"| K{"or {} normalizes to dict"}
K --> L["extra_body = {}"]
L --> M["Safe dict unpacking: **extra_body"]
Last reviewed commit: 7c77495
Review1. Does this PR fix the issue it describes? Applied to 7+ providers per Greptile recommendations (Azure, Snowflake, OVHCloud, CometAPI, OpenRouter, WatsonX, Azure AI). 2. Has this issue already been solved elsewhere? 3. Are there other PRs addressing the same problem? 4. Are there other issues this potentially closes? ✅ LGTM — comprehensive fix across providers with good test coverage (137 LOC). |
|
any update? |
|
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. |
Relevant issues
Fixes #21891
What changed
When
extra_bodyis explicitly passed asNone(e.g. vialitellm.responses(..., extra_body=None)), two code paths would crash withTypeError: 'NoneType' object is not a mappingwhen trying to unpack**extra_bodyor**optional_params["extra_body"].Fix 1 —
litellm/llms/openai_like/chat/handler.pyNormalize
extra_bodyafter popping fromoptional_params:Fix 2 —
litellm/utils.py(add_provider_specific_params_to_optional_params)extra_bodyfrompassed_params:optional_params["extra_body"]beingNonewhen merging:Testing
TypeError: 'NoneType' object is not a mappingwhenextra_body=Noneis passed to OpenAI-compatible providers (includinghosted_vllm) via Router or/responsesendpointAdditional fixes (greptile-bot recommendations)
Applied the same
or {}normalization to all other providers with the identical vulnerable pattern:litellm/llms/snowflake/chat/transformation.pylitellm/llms/ovhcloud/chat/transformation.pylitellm/llms/cometapi/chat/transformation.pylitellm/llms/openrouter/chat/transformation.pylitellm/llms/azure/azure.py(image generation)litellm/llms/azure_ai/chat/transformation.pylitellm/llms/watsonx/completion/transformation.pyAdded unit tests in
tests/litellm/llms/openai_like/test_extra_body_none_fix.pycovering:extra_body=Nonedoes not raise TypeError (OpenAI-like handler)extra_body={}(empty dict) continues to workextra_body={...}with real keys is correctly mergedget_optional_paramswithextra_body=Nonefor openai, hosted_vllm, openrouter providers