fix(openai): filter None values from embedding optional_params (encoding_format=null)#24277
fix(openai): filter None values from embedding optional_params (encoding_format=null)#24277IvoryKir wants to merge 3 commits intoBerriAI:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR applies the same Changes:
Minor observation: The filter ( Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| litellm/llms/openai/openai.py | Adds a filter to remove None and "" values from optional_params before building the embedding request data dict, mirroring the pattern already in the openai_like handler. The filtered data dict is correctly passed to both the sync and async paths. |
| tests/test_litellm/llms/openai/embedding/test_openai_embedding_encoding_format.py | New mock-only test file covering 6 cases (None, empty string, float, base64, other params, empty dict). Uses patch.object on make_sync_openai_embedding_request and _get_openai_client, and also patches convert_to_model_response_object to prevent false failures on unrelated validation. No real network calls are made. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["OpenAIChatCompletion.embedding()"] --> B["Build filtered_optional_params\n{k: v for k, v in optional_params.items()\n if v not in (None, '')}"]
B --> C["data = {model, input, **filtered_optional_params}"]
C --> D{aembedding?}
D -- "True (async)" --> E["aembedding(data=data, ...)"]
D -- "False (sync)" --> F["_get_openai_client()"]
F --> G["make_sync_openai_embedding_request(data=data, ...)"]
G --> H["convert_to_model_response_object()"]
E --> H
H --> I["Return EmbeddingResponse"]
style B fill:#c8f7c5,stroke:#27ae60
style C fill:#c8f7c5,stroke:#27ae60
Last reviewed commit: "fix(tests): mock con..."
Filter out None and empty string values from optional_params before constructing the embedding request data dictionary. This prevents sending encoding_format=null to OpenAI-compatible servers (llama.cpp, vLLM, TEI, LocalAI) that have strict JSON parsers and reject null values where a string is expected: [json.exception.type_error.302] type must be string, but is null The openai_like embedding handler already applies this filter (openai_like/embedding/handler.py L108-110), but the generic openai handler did not, causing failures when users set api_base to point to local embedding servers. This is a follow-up to the vLLM embeddings incident where the same pattern was applied to the openai_like handler. Refs: https://docs.litellm.ai/blog/vllm-embeddings-incident BerriAI#19174 Signed-off-by: IvoryKir <ivory.kir@gmail.com>
a3039c0 to
75993c6
Compare
tests/test_litellm/llms/openai/embedding/test_openai_embedding_encoding_format.py
Outdated
Show resolved
Hide resolved
tests/test_litellm/llms/openai/embedding/test_openai_embedding_encoding_format.py
Outdated
Show resolved
Hide resolved
|
The lint CI failure is unrelated to this PR — Black flags |
Summary
Filter out
Noneand empty string values fromoptional_paramsin the generic OpenAI embedding handler before constructing the request, preventingencoding_format: nullfrom being sent to custom endpoints.Problem
When using
litellm.embedding()with theopenaiprovider and a customapi_basepointing to a local embedding server (llama.cpp, vLLM, TEI, etc.), the request includesencoding_format: nullin the JSON body. Strict JSON parsers reject this:This was already fixed for the
openai_likehandler (L108-110 inlitellm/llms/openai_like/embedding/handler.py) after the vLLM embeddings incident, but the same filter was not applied to the genericopenaihandler inlitellm/llms/openai/openai.py.Users hitting this issue use the
openaiprovider withapi_baseto point to local servers — a common pattern for llama.cpp, TEI, LocalAI, etc.Fix
Apply the exact same filtering pattern from
openai_likehandler to the genericopenaihandler:Impact
api_baseendpoints that reject null JSON valuesopenai_likehandler's existing approachRefs
litellm/llms/openai_like/embedding/handler.pyL108-110