fix: handle explicit outputInfo: null in Vertex AI batch response - #34097
Closed
htourinho-clgx wants to merge 3 commits into
Closed
fix: handle explicit outputInfo: null in Vertex AI batch response#34097htourinho-clgx wants to merge 3 commits into
htourinho-clgx wants to merge 3 commits into
Conversation
Vertex AI can return HTTP 200 for a create_batch/get_batch call with an
explicit "outputInfo": null body (the output directory is assigned
asynchronously and may not be populated yet at response time).
_get_output_file_id_from_vertex_ai_batch_response did:
response.get("outputInfo", OutputInfo()).get("gcsOutputDirectory", "")
dict.get(key, default) only substitutes default when the key is absent,
not when it is present but explicitly None, so this crashed with:
AttributeError: 'NoneType' object has no attribute 'get'
surfaced to callers as an opaque openai.InternalServerError 500 from
litellm.create_batch()/retrieve_batch() for any Vertex AI batch job,
regardless of whether the job ultimately succeeds.
Fixed by guarding with `response.get("outputInfo") or OutputInfo()`,
matching the existing null-safe pattern already used by the sibling
_get_input_file_id_from_vertex_ai_batch_response for inputConfig. The
existing outputConfig fallback branch (a few lines below) already
handles this case correctly once it's reachable - it just never was.
Added 2 regression tests covering outputInfo: null with and without an
outputConfig fallback available.
Contributor
Greptile SummaryThis PR fixes null handling in Vertex AI batch responses and updates dashboard dependencies. The main changes are:
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| litellm/llms/vertex_ai/batches/transformation.py | Normalizes null output information before reading the output directory, preserving the existing fallback behavior. |
| tests/test_litellm/llms/vertex_ai/batches/test_transformation.py | Adds focused tests for explicit null output information with and without an output configuration. |
| ui/litellm-dashboard/package.json | Updates the dashboard overrides for js-yaml and brace-expansion. |
| ui/litellm-dashboard/package-lock.json | Records the updated dependency resolutions and optional bundled packages. |
Reviews (2): Last reviewed commit: "chore(ui): bump brace-expansion and js-y..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
htourinho-clgx
changed the base branch from
main
to
litellm_oss_daily_2026_07_20
July 21, 2026 12:22
Bumps transitive npm dev-dependencies flagged by the repo's osv-scan CI check (unrelated to the Vertex AI batch fix in this PR, but needed for CI to pass): - js-yaml 4.2.0 -> 4.3.0 (GHSA-52cp-r559-cp3m) - brace-expansion 5.0.6 -> 5.0.7 (GHSA-3jxr-9vmj-r5cp) Both pinned via the existing 'overrides' block in ui/litellm-dashboard/package.json (js-yaml was already pinned there; added brace-expansion alongside it). No direct dependency changes - only transitive resolution. Verified locally with the exact osv-scanner command CI runs: 'No issues found'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5 tasks
5 tasks
Contributor
Contributor
|
bugbot run |
Contributor
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2cbec23. Configure here.
Contributor
|
This has been merged into staging with a copy branch #34473. Thank you for your contribution! |
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.
Relevant issues
litellm.create_batch()/retrieve_batch()against a Vertex AI-backedmodel can raise an opaque
openai.InternalServerError: 500 - "'NoneType' object has no attribute 'get'"if Vertex AI returns HTTP 200 with anexplicit
"outputInfo": nullbody - the output directory is assignedasynchronously by Vertex and is not always populated in the synchronous
response.
Correction (please read): an earlier version of this PR description
stated this was confirmed as a live incident in our own environment,
"with the exact vulnerable line ... present, unpatched, in the specific
litellm version pinned in that environment (1.83.10)". That claim was
based on a version pin in a dependency file, not on the actually deployed
proxy image. After checking the real running container version directly
(Helm/Kubernetes labels on the live pods, both in our dev and UAT
environments), the version actually deployed there is
1.72.2, whichpredates this code path entirely (
_get_output_file_id_from_vertex_ai_batch_responsein 1.72.2 doesn't reference
outputInfoat all - it uses a different,fully null-guarded
outputConfig.gcsDestinationpath). The real incidentthat triggered our investigation was therefore not this bug - it was a
separate, unrelated defect, which we've filed separately as
#34260.
Apologies for the earlier inaccurate evidence claim. The code defect this
PR fixes is still real and independently verified by direct source
inspection (see below) - we're just no longer claiming a live production
reproduction of this specific bug from our side, since we can't honestly
back that claim with our own incident.
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Found via direct source code review, not a live incident on our side:
confirmed the exact vulnerable, unguarded
outputInfo.get(...)call ispresent in litellm 1.83.10, 1.85.1, 1.92.0, and 1.93.0 by inspecting the
real published source of each version directly. We do not currently run
any of these versions in our own deployed environments, so we can't supply
a live before/after from production - the reproduction below uses the real
function from this PR's diff, called directly with the exact response
shape Vertex AI's own API is documented to allow.
At commit
090c2e1:Before (pre-fix code):
dict.get(key, default)only substitutesdefaultwhen the key isabsent, not when it's present but explicitly
None- this is what crasheswhenever Vertex returns
outputInfo: null.After (this PR's code, same input):
No crash; falls through cleanly to the
outputConfig-derived path.Also covered by the 2 new regression tests in
tests/test_litellm/llms/vertex_ai/batches/test_transformation.py(
test_get_output_file_id_output_info_explicit_none_falls_through_to_output_config,test_get_output_file_id_output_info_explicit_none_and_no_output_config),confirmed passing alongside all 44 pre-existing tests in that file.
Type
🐛 Bug Fix
Changes
litellm/llms/vertex_ai/batches/transformation.py: guardoutputInfobeingexplicitly
Nonebefore calling.get()on it, matching the null-safepattern already used by the sibling
_get_input_file_id_from_vertex_ai_batch_response.tests/test_litellm/llms/vertex_ai/batches/test_transformation.py: 2 newregression tests for
outputInfo: null, with and without anoutputConfigfallback available.
Final Attestation
regressions in the respective real-world customer use-cases are not
possible after this PR
Note
Low Risk
Narrow null-handling fix in batch response mapping with targeted tests; dashboard dependency override bumps are routine.
Overview
Fixes a crash in
_get_output_file_id_from_vertex_ai_batch_responsewhen Vertex AI returns HTTP 200 with"outputInfo": null. The previous code usedresponse.get("outputInfo", OutputInfo()).get(...), which does not substitute the default when the key is present but null, leading toAttributeErrorand a surfaced 500 from batch create/retrieve.The change normalizes
outputInfowithresponse.get("outputInfo") or OutputInfo()before readinggcsOutputDirectory, so parsing can fall through tooutputConfig.gcsDestinationwhen the async output directory is not set yet.Two regression tests cover
outputInfo: nullwith and without anoutputConfigfallback. The dashboardpackage.jsonoverrides bumpjs-yamlandbrace-expansion(lockfile updated accordingly).Reviewed by Cursor Bugbot for commit 2cbec23. Bugbot is set up for automated code reviews on this repo. Configure here.