Skip to content

fix(gemini): avoid duplicate model route for full api_base#26983

Closed
StatPan wants to merge 3 commits into
BerriAI:litellm_oss_stagingfrom
StatPan:fix/gemini-full-api-base-duplicate-path-clean
Closed

fix(gemini): avoid duplicate model route for full api_base#26983
StatPan wants to merge 3 commits into
BerriAI:litellm_oss_stagingfrom
StatPan:fix/gemini-full-api-base-duplicate-path-clean

Conversation

@StatPan
Copy link
Copy Markdown

@StatPan StatPan commented May 1, 2026

Summary

  • avoid appending a duplicate /models/{model}:{endpoint} route when Gemini api_base already includes the full route
  • handle api_base values that already point at /models/{model} prefixes without duplicating the model path
  • add regression coverage for both full-route and full-model-prefix custom api_base handling

Validation

  • uv run pytest tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py -k 'custom_proxy or full_route or api_base or credential_project_validation'
  • uv run ruff check litellm/llms/vertex_ai/vertex_llm_base.py tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py

Context

This is the clean OSS-staging re-open of the same fix after identifying that the previous PR routing was wrong and the branch ancestry pulled in unrelated diff.

Related:

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 1, 2026

Greptile Summary

This PR fixes a URL-construction bug in _check_custom_proxy where a Gemini api_base that already contained the full /models/{model}:{endpoint} route (or the model-only prefix) would have an extra segment appended. The fix adds two early-exit branches and a rstrip("/") improvement. Tests are well-targeted: unused imports are removed, a pre-existing missing assertion is added, and three new parametrized cases cover the new logic.

Confidence Score: 4/5

Safe to merge; the fix is minimal and correct for the documented cases, with one unhandled edge case left as a P2 suggestion.

Only P2 findings present. The three-branch guard correctly handles all cases described in the PR. One unhandled edge case (full-route api_base with a mismatched endpoint) could silently produce a bad URL but is very unlikely in practice and is no worse than the pre-fix behaviour.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/vertex_ai/vertex_llm_base.py Adds three-way branch in _check_custom_proxy to avoid duplicating /models/{model}:{endpoint} when the Gemini api_base already includes the full route or the model prefix; also adds rstrip("/") to the base-URL case.
tests/test_litellm/llms/vertex_ai/test_vertex_llm_base.py Removes unused imports, converts an incomplete print statement into a proper assertion, and adds a parametrized regression test for the three new api_base shapes.

Reviews (1): Last reviewed commit: "test(vertex): restore credential project..." | Re-trigger Greptile

Comment on lines +415 to +422
if api_base.endswith(f"/models/{model}:{endpoint}"):
url = api_base
elif api_base.endswith(f"/models/{model}"):
url = f"{api_base}:{endpoint}"
else:
url = "{}/models/{}:{}".format(
api_base.rstrip("/"), model, endpoint
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 If a user sets api_base to a full route that already contains a different endpoint than the one being requested (e.g. api_base ends with :generateContent but the call needs :streamGenerateContent), none of the first two branches match and the else branch appends /models/{model}:{endpoint} onto an already-fully-routed base, producing a malformed URL. A guard on the broader /models/{model}: pattern would prevent this from silently constructing a wrong URL.

Suggested change
if api_base.endswith(f"/models/{model}:{endpoint}"):
url = api_base
elif api_base.endswith(f"/models/{model}"):
url = f"{api_base}:{endpoint}"
else:
url = "{}/models/{}:{}".format(
api_base.rstrip("/"), model, endpoint
)
if api_base.endswith(f"/models/{model}:{endpoint}"):
url = api_base
elif api_base.endswith(f"/models/{model}"):
url = f"{api_base}:{endpoint}"
elif f"/models/{model}:" in api_base:
# api_base already contains a routed path for this model but
# with a different endpoint – swap the endpoint rather than
# appending a second /models/… segment.
url = api_base[: api_base.rfind(f"/models/{model}:")] + f"/models/{model}:{endpoint}"
else:
url = "{}/models/{}:{}".format(
api_base.rstrip("/"), model, endpoint
)

@codecov
Copy link
Copy Markdown

codecov Bot commented May 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@StatPan
Copy link
Copy Markdown
Author

StatPan commented May 14, 2026

Quick follow-up: I closed the earlier routing attempts (#26980, #26982) so this PR is now the only active PR for the Gemini custom api_base fix.

This is the clean review path:

The bug breaks deployments where api_base already includes the full Gemini model route because LiteLLM appends /models/{model}:{endpoint} a second time. Would appreciate a maintainer review when possible.

@oss-pr-review-agent-shin
Copy link
Copy Markdown
Contributor

🤖 litellm-agent: This PR is currently BLOCKED from merge.

Score: 4/5

Why blocked:

  • 1 unresolved reviewer concern (greptile) (unresolved_concern, -1 pts)

Details: Score docked for: 1 unresolved reviewer concern (greptile).

Fix the issues above and push an update — the bot will re-review automatically.

Note: This bot is still in beta and might not always work as expected. Please share any feedback via Slack.

@StatPan
Copy link
Copy Markdown
Author

StatPan commented May 14, 2026

Hi maintainers, gentle ping on this bug fix.

This PR is now the only active PR for #26979 after closing the earlier routing attempts. It is a small 2-file change against litellm_oss_staging, CI is green, and it fixes Gemini custom api_base values that already include the full model route.

Could someone take a look when possible, or let me know if this should be routed differently?

@mateo-berri mateo-berri deleted the branch BerriAI:litellm_oss_staging May 18, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants