fix(passthrough): forward all multipart files with repeated field names#31391
Conversation
Passthrough multipart uploads used form.items() and a files dict, so only the last file under a repeated field name reached the upstream. Read multi_items() and send httpx a list of file tuples instead. Co-authored-by: Cursor <[email protected]>
|
Shivam Rawat seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
Greptile SummaryFixes multipart passthrough dropping all but the last file when a client sends multiple parts under the same field name (e.g.
Confidence Score: 5/5Safe to merge — the change is a targeted, well-tested fix to multipart forwarding with no impact on other request paths. The fix is correct: No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/pass_through_endpoints/pass_through_endpoints.py | Switches multipart form parsing from form.items() to form.multi_items(), emits files as a list of tuples, and groups repeated non-file fields into list values — correctly forwarding all parts under duplicate field names. |
| tests/test_litellm/proxy/pass_through_endpoints/test_pass_through_endpoints.py | Updates existing multipart tests to use FormData([...]) and assert on the list-of-tuples shape; adds a dedicated regression test covering repeated file and non-file fields under the same key. |
Reviews (2): Last reviewed commit: "refactor(passthrough): address multipart..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Build form_data_dict in one pass with groupby instead of rescanning form_items per field name, and assert on the files list directly in the boundary regression test so repeated field names are not collapsed by dict(). Co-authored-by: Cursor <[email protected]>
|
@greptile review again with new commit that resolves the p2 issues |
Fixes LIT-4043
Relevant issues
Fixes passthrough multipart uploads dropping files when a client sends several parts under the same field name (e.g. multiple -F file=@...)
Summary
Passthrough multipart forwarding in make_multipart_http_request used form.items() and a files dict keyed by field name. Starlette's FormData.items() keeps only the last value for duplicate keys, and a dict cannot hold multiple entries under the same key anyway, so only one file reached the upstream backend
The handler now reads form.multi_items(), builds files as a list of (field_name, (filename, content, content_type)) tuples for httpx, and groups repeated non-file fields into list values in data. httpx encodes both as separate multipart parts
Type
Bug Fix
Changes
litellm/proxy/pass_through_endpoints/pass_through_endpoints.py: iterate multi_items() and forward files as a list of tuples instead of a dict
tests/test_litellm/proxy/pass_through_endpoints/test_pass_through_endpoints.py: update existing multipart tests for the new httpx shape; add test_make_multipart_http_request_forwards_repeated_fields regression test
Before:

After:
