litellm - ✅(Solved) Fix [Bug]: Budget limits bypassed when 'LiteLLM Model Name' does not follow 'provider/model_name' format in Proxy UI [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#24770Fetched 2026-04-08 01:49:13
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
labeled ×2closed ×1cross-referenced ×1

Root Cause

Current behavior

  • The UI allows saving a model name without the provider prefix.
  • The backend matches the request based on the exposed Model Name but fails to correctly attribute the spend to the budget tracker because the internal model identifier is ambiguous/incorrect.
  • Budget checks are bypassed, allowing unlimited usage.

PR fix notes

PR #24949: fix(auth): enforce budget for models not in cost map

Description (problem / solution / changelog)

Relevant issues

Fixes https://github.com/BerriAI/litellm/issues/24770 Related: https://github.com/BerriAI/litellm/issues/23714

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🐛 Bug Fix

Changes

Models not in litellm.model_cost get sparse entries (e.g. {"id": "<hash>"}) during Router initialization. _get_model_info_helper() defaults their missing cost fields to 0, and _is_model_cost_zero() interprets this as "genuinely free model," bypassing all budget enforcement (key, user, team, end-user, and org budgets).

Fix:

  • Added _is_cost_explicitly_configured() in litellm/proxy/auth/auth_checks.py — checks the raw litellm.model_cost entry for actual cost fields to distinguish "explicitly free" from "unknown cost due to sparse auto-registration entry"
  • _is_model_cost_zero() now calls this helper when costs are 0. Sparse entries → enforce budget. Explicit 0.0 config → bypass budget (preserving #14004 behavior for free on-prem models)
  • Changed ModelMapInfo fallback in litellm/router.py from 0 to None (defense-in-depth — None means "unknown cost")
  • Updated type annotations in litellm/types/utils.py to Required[Optional[float]] to support None cost values

Tests: 4 new tests in tests/test_litellm/proxy/auth/test_unmapped_model_budget_enforcement.py covering unmapped models, explicitly free models, known paid models, and litellm_params pricing. All 17 existing zero-cost budget bypass tests continue to pass.

Changed files

  • litellm/proxy/auth/auth_checks.py (modified, +44/-2)
  • litellm/router.py (modified, +2/-2)
  • litellm/types/utils.py (modified, +2/-2)
  • tests/test_litellm/proxy/auth/test_unmapped_model_budget_enforcement.py (added, +108/-0)
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

Body:

Describe the bug Despite setting budgets on virtual keys, key owners, and teams, requests continue to succeed even after the budget limit is exceeded. This issue occurs specifically when the model is configured in the Proxy UI without following the required provider/model_name naming convention.

Expected behavior

  • The UI should enforce the provider/model_name format (e.g., hosted_vllm/Qwen3-4B) during model creation.
  • OR, the backend should automatically normalize the model name to include the provider prefix for budget tracking logic.
  • Requests should be blocked once the budget limit is exceeded, regardless of the model name format.

Current behavior

  • The UI allows saving a model name without the provider prefix.
  • The backend matches the request based on the exposed Model Name but fails to correctly attribute the spend to the budget tracker because the internal model identifier is ambiguous/incorrect.
  • Budget checks are bypassed, allowing unlimited usage.

Screenshots <img width="1697" height="865" alt="Image" src="https://github.com/user-attachments/assets/e7c12e7e-ce7d-42c9-adfc-cf7d603619c5" />

Proposed Solution

  1. Frontend Validation: Prevent users from saving a LiteLLM Model Name in the UI if it does not match the selected provider's expected format (e.g., force hosted_vllm/ prefix when vllm is selected).
  2. Backend Normalization: When processing requests, if the model name matches an exposed model but lacks the provider prefix, the backend should resolve the correct internal model identifier before performing budget checks.

Steps to Reproduce

  1. Start LiteLLM Proxy and access the UI.
  2. Create a Virtual Key and assign a Budget (e.g., $1.00).
  3. In the Model Management section, add a new model:
    • Select Provider: vllm (or any specific provider)
    • In LiteLLM Model Name(s): Choose Custom Model Name (Enter below)
    • Input LiteLLM Model Name: "Qwen3-4B" (❌ Intentionally omitting the "hosted_vllm/" prefix).
    • Input the exposed Model Name, such as "FREE".
    • Send requests using this model until the budget limit is reached.
  4. Observe that requests continue to succeed without being blocked.

Relevant log output

What part of LiteLLM is this about?

UI Dashboard

What LiteLLM version are you on ?

v1.82.6.dev2

Twitter / LinkedIn details

No response

extent analysis

Fix Plan

To address the issue, we need to implement two main fixes:

  1. Frontend Validation: Enforce the provider/model_name format in the UI.
  2. Backend Normalization: Normalize the model name to include the provider prefix for budget tracking logic.

Frontend Validation

// Example frontend validation code
const selectedProvider = 'vllm'; // Get the selected provider
const modelNameInput = 'Qwen3-4B'; // Get the input model name

if (!modelNameInput.startsWith(`${selectedProvider}/`)) {
  // Prevent saving if the model name does not match the expected format
  alert('Model name must be in the format "provider/model_name"');
  return;
}

Backend Normalization

# Example backend normalization code
def normalize_model_name(model_name, provider):
    if not model_name.startswith(f'{provider}/'):
        # Resolve the correct internal model identifier
        model_name = f'{provider}/{model_name}'
    return model_name

# Usage
provider = 'hosted_vllm'
model_name = 'Qwen3-4B'
normalized_model_name = normalize_model_name(model_name, provider)
print(normalized_model_name)  # Output: hosted_vllm/Qwen3-4B

Verification

To verify the fix, follow these steps:

  • Create a new model with a custom name without the provider prefix.
  • The UI should prevent saving the model.
  • Create a new model with a valid name (including the provider prefix).
  • Send requests until the budget limit is reached.
  • The backend should block further requests once the budget limit is exceeded.

Extra Tips

  • Ensure that the provider prefix is correctly configured for each provider.
  • Consider adding additional validation for model names to prevent similar issues in the future.
  • Review the budget tracking logic to ensure it correctly handles normalized model names.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING