Skip to content

fix(ui): stop pairing key spend with the team budget when a key has no budget - #37196

Merged
ryan-crabbe-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_key_budget_no_team_fallback
Aug 17, 2026
Merged

fix(ui): stop pairing key spend with the team budget when a key has no budget#37196
ryan-crabbe-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_key_budget_no_team_fallback

Conversation

@ryan-crabbe-berri

@ryan-crabbe-berri ryan-crabbe-berri commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Budgetless key on a budgeted team showed "spend of $team-budget"
  • Key spend metered against the team's aggregate cap: a nonsense ratio
  • Same mismatch on the key overview card and the Virtual Keys table

How it solves it:

  • Budgetless keys show "Unlimited" again on both surfaces
  • New hover hint lists inherited team and org budgets, if any
  • Shared InheritedBudgetHint + inheritedBudgetGates helper, unit tested

User Flow

Before: an admin opening a key that has no budget of its own but sits on a team with one is told the key has that team's budget

  1. They open http://localhost:4000/ui/?page=api-keys and see the row for the key read $0.00 of $1,200 (Team) with a progress meter under it
  2. They click the key and land on http://localhost:4000/ui/?page=api-keys&key=<key_id>
  3. The Spend card reads $0.0000 of $1,200.00 (Team: qa-budget-hint-team / 30d), as if this one key had a $1,200 cap and had used 0% of it
  4. Nothing on either surface mentions that the $1,200 is shared by every key on the team, or that the team's organization caps it further at $5,000

After: the same key reads as unlimited, and hovering the hint explains what still gates it

  1. They open http://localhost:4000/ui/?page=api-keys and see the row read $0.00 · Unlimited with a small question-mark icon and no meter
  2. They click the key and land on http://localhost:4000/ui/?page=api-keys&key=<key_id>
  3. The Spend card reads $0.0000 of Unlimited with the same question-mark icon next to it
  4. Hovering the icon shows "This key has no budget of its own, but its spend still counts toward: Team qa-budget-hint-team: $1,200.00 / 30d, Organization qa-budget-hint-org: $5,000.00"
  5. A key on a team with no budget shows of Unlimited with no icon; a key with its own budget shows of $25.00 with no icon

Relevant issues

Reverts the display fallback added in #30801

Linear ticket

Resolves LIT-5649

Pre-Submission checklist

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

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

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

Setup, against the dev proxy on localhost:4000 with the master key:

ORG_ID=$(curl -s localhost:4000/organization/new -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"organization_alias":"qa-budget-hint-org","max_budget":5000}' | jq -r .organization_id)
TEAM_ID=$(curl -s localhost:4000/team/new -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d "{\"team_alias\":\"qa-budget-hint-team\",\"max_budget\":1200,\"budget_duration\":\"30d\",\"organization_id\":\"$ORG_ID\"}" | jq -r .team_id)
FREE_TEAM_ID=$(curl -s localhost:4000/team/new -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"team_alias":"qa-budget-hint-free-team"}' | jq -r .team_id)
for spec in "qa-hint-key-inherits:$TEAM_ID:null" "qa-hint-key-own-budget:$TEAM_ID:25" "qa-hint-key-free-team:$FREE_TEAM_ID:null"; do
  IFS=: read alias tid mb <<< "$spec"
  curl -s localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
    -d "{\"key_alias\":\"$alias\",\"team_id\":\"$tid\",\"max_budget\":$mb}" | jq -r '"\(.key_alias) \(.token_id) max_budget=\(.max_budget)"'
done

Output:

qa-hint-key-inherits 81914ee31c24157c88efeed8ebdce45133c3bce4403b3bcc77bc14474a5aaaa5 max_budget=null
qa-hint-key-own-budget e06b011b8ff118ee400086192082e5d06763bf9d4d8ea33a86411c309d938622 max_budget=25
qa-hint-key-free-team c57580e9728993e24889b62e79944e856773916c5b1498178218fa4b9e478dc7 max_budget=null

Before (1dbed6e)

Virtual Keys table

  1. Open http://localhost:4000/ui/?page=api-keys and search qa-hint
  2. qa-hint-key-inherits reads $0.00 of $1,200 (Team) with a meter under it

before table

Key overview card

  1. Click qa-hint-key-inherits
  2. Spend card reads $0.0000 of $1,200.00 (Team: qa-budget-hint-team / 30d)

before card

After (6fc6f3c)

Virtual Keys table

  1. Open http://localhost:4000/ui/?page=api-keys and search qa-hint
  2. qa-hint-key-inherits reads $0.00 · Unlimited with a question-mark icon and no meter; hovering the icon lists Team qa-budget-hint-team: $1,200.00 / 30d and Organization qa-budget-hint-org: $5,000.00
  3. qa-hint-key-free-team reads $0.00 · Unlimited with no icon; qa-hint-key-own-budget reads $0.00 of $25 with a meter and no icon

after table, hint hovered

Key overview card

  1. Click qa-hint-key-inherits
  2. Spend card reads $0.0000 of Unlimited with the icon; hovering shows the same team and organization lines
  3. qa-hint-key-free-team shows of Unlimited with no icon; qa-hint-key-own-budget shows of $25.00 with no icon

after card

after card, hint hovered

Type

🐛 Bug Fix

Caveats (if any)

  • Hint reads the org via the key's org, else the team's org
  • User-level budgets are not listed in the hint

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

…o budget

The key overview card and the Virtual Keys spend meter fell back to the parent team's max_budget as the denominator while the numerator stayed the key's own spend, so a $0.50 key on a $1,200 team read as "$0.50 of $1,200 (Team)" and drew a meter against a limit that governs the whole team's aggregate spend, not this key. Both surfaces now show Unlimited for a budgetless key and, when the parent team or organization does carry a budget, a hover hint listing those inherited caps so the reader knows what still gates the key
…itellm_key_budget_no_team_fallback

# Conflicts:
#	ui/litellm-dashboard/src/components/templates/key_info_view.tsx
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR corrects virtual-key budget presentation so key spend is no longer compared with inherited team budgets.

  • Adds a shared inherited-budget hint for applicable team and organization limits.
  • Uses the hint in both the Virtual Keys table and key overview.
  • Updates unit and component tests for owned, inherited, and unlimited budget states.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking defects identified.

The changed UI consistently separates a key's own budget from inherited team and organization gates, and the updated tests cover the principal display states on both affected surfaces.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/shared/InheritedBudgetHint.tsx Introduces a focused helper and tooltip component that safely derives and formats team and organization budget gates.
ui/litellm-dashboard/src/components/shared/table_cells/spend_budget_cell.tsx Stops metering key spend against inherited budgets and displays inherited limits only as contextual information.
ui/litellm-dashboard/src/components/VirtualKeysPage/keyTableColumns.tsx Resolves the key's team and organization and supplies inherited gates only for budgetless keys.
ui/litellm-dashboard/src/components/templates/key_info_view.tsx Displays budgetless keys as unlimited and adds inherited team or organization context without changing enforcement.
ui/litellm-dashboard/src/components/templates/key_info_view.budget_display.test.tsx Covers owned, team-inherited, organization-inherited, and fully unlimited key-budget displays.

Reviews (1): Last reviewed commit: "fix(ui): stop pairing key spend with the..." | Re-trigger Greptile

@ryan-crabbe-berri
ryan-crabbe-berri merged commit d0a815d into litellm_internal_staging Aug 17, 2026
67 of 68 checks passed
@ryan-crabbe-berri
ryan-crabbe-berri deleted the litellm_key_budget_no_team_fallback branch August 17, 2026 20:03
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