Skip to content

fix(ui): render team and org tpm/rpm limits of 0 as 0 instead of Unlimited - #37916

Merged
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_/repo-autofix-feasibility-648801
Aug 24, 2026
Merged

fix(ui): render team and org tpm/rpm limits of 0 as 0 instead of Unlimited#37916
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_/repo-autofix-feasibility-648801

Conversation

@yuneng-berri

@yuneng-berri yuneng-berri commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Team and org views render tpm_limit / rpm_limit of 0 as "Unlimited"
  • 0 is a hard block on the backend, null is unlimited
  • Edit Member dialog rewrites a stored 0 to null on an untouched Save

How it solves it:

  • Every limit display site uses a nullish check instead of a falsy one
  • Member form seeding keeps 0 for budget, tpm and rpm limits
  • Regression tests cover each display site and the form seeding

User Flow

Before: an admin who set a team's TPM limit to 0 to block it sees the team described as unlimited, and re-saving a blocked member quietly unblocks them

  1. They send POST https://litellm-domain/team/update with {"team_id": "...", "tpm_limit": 0} and get back tpm_limit: 0
  2. A key on that team sends POST https://litellm-domain/v1/chat/completions and gets 429 "Rate limit exceeded for team ... Current limit: 0"
  3. They open https://litellm-domain/ui/?page=teams, click the team, and the Overview reads "TPM: Unlimited" and "RPM: Unlimited"
  4. On the Members tab they click Edit on a member whose limit is stored as 0, change nothing, and click Save
  5. The request to POST https://litellm-domain/team/member_update carries "tpm_limit": null, and that member's hard block is gone

After: the same admin sees the 0 they set, and saving a member without touching the limit leaves it at 0

  1. They send POST https://litellm-domain/team/update with {"team_id": "...", "tpm_limit": 0} and get back tpm_limit: 0
  2. A key on that team sends POST https://litellm-domain/v1/chat/completions and gets 429 "Rate limit exceeded for team ... Current limit: 0"
  3. They open https://litellm-domain/ui/?page=teams, click the team, and the Overview reads "TPM: 0" and "RPM: 0"
  4. On the Members tab they click Edit on a member whose limit is stored as 0, change nothing, and click Save
  5. The request to POST https://litellm-domain/team/member_update carries "tpm_limit": 0, and the member stays blocked

Relevant issues

Linear ticket

Resolves LIT-5760

Pre-Submission checklist

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

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • 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

Shared setup, against a local proxy on :4000 with the dashboard dev server on :3000

curl -s http://localhost:4000/team/new -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"team_alias":"tpm-zero","tpm_limit":0,"rpm_limit":0}'
curl -s http://localhost:4000/team/member_add -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"team_id":"<team_id from above>","member":{"role":"user","user_email":"blocked@example.com"},"tpm_limit":0}'

Before (7481649)

Team overview renders 0 as Unlimited

  1. Open http://localhost:3000/teams/ and click tpm-zero
  2. Overview shows "TPM: Unlimited" and "RPM: Unlimited"

Edit Member rewrites 0 to null

  1. On the Members tab click Edit on blocked@example.com, leave every field untouched, click Save
  2. The /team/member_update request body in the browser network tab carries "tpm_limit": null

After (d124a00)

Team overview renders 0 as Unlimited

  1. Open http://localhost:3000/teams/ and click tpm-zero
  2. Overview shows "TPM: 0" and "RPM: 0"

Edit Member rewrites 0 to null

  1. On the Members tab click Edit on blocked@example.com, leave every field untouched, click Save
  2. The /team/member_update request body carries "tpm_limit": 0

Type

🐛 Bug Fix

Caveats (if any)

  • 0 still renders as a bare 0 rather than an explicit "blocked" label; whether 0 should stay a supported way to block a team is a separate decision

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

…mited

A tpm_limit or rpm_limit of 0 is a hard block on the backend (every request 429s) and only null means unlimited, but the team and organization views rendered both as "Unlimited" (and a team-member limit of 0 as "No Limit") because every display site used a falsy || fallback. The team member edit dialog also seeded its form with `tpm_limit || null`, so opening Edit Member on a member stored with 0 and clicking Save sent null to /team/member_update and silently turned the hard block into unlimited

Every limit display site in TeamInfo, organization_view, the organizations list cell and the team members table now uses a nullish check, and both member form seeding paths keep 0 for max_budget_in_team, tpm_limit and rpm_limit. Regression tests cover each site and the existing memberFormValues test that asserted 0 -> null is flipped to assert 0 survives

Resolves LIT-5760
@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR preserves explicit zero-valued team, organization, and member limits throughout dashboard rendering and member form submission

  • Replaces falsy checks with nullish checks at team and organization display sites
  • Preserves stored zero values when seeding and submitting member forms
  • Adds regression coverage for zero-valued limits and immutable fixture construction

Confidence Score: 5/5

The PR appears safe to merge

No blocking failure remains

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/team/TeamMemberTab.test.tsx The previous nested fixture mutation is fully replaced with immutable map and spread construction
ui/litellm-dashboard/src/components/team/TeamMemberTab.tsx Member limit rendering and edit payload construction now distinguish zero from an absent limit
ui/litellm-dashboard/src/components/team/memberFormValues.ts Member form seeding now preserves explicit zero-valued budgets and rate limits
ui/litellm-dashboard/src/components/team/TeamInfo.tsx Team overview and settings displays now render zero limits without treating them as unlimited
ui/litellm-dashboard/src/components/organization/organization_view.tsx Organization overview and settings displays now distinguish zero limits from null
ui/litellm-dashboard/src/app/(dashboard)/organizations/_components/OrganizationsTableColumns.tsx Organization table limit cells now render explicit zero values correctly

Reviews (2): Last reviewed commit: "test(ui): assert a stored 0 member limit..." | Re-trigger Greptile

Comment thread ui/litellm-dashboard/src/components/team/TeamMemberTab.test.tsx Outdated
The EditMembership integration test named the old 0 -> null collapse as the expected payload, so the related-tests CI job went red once the form kept 0. It now asserts 0 survives and only the empty budget_duration collapses to null. The TeamMemberTab fixture is built with a map instead of mutating the nested membership
@yuneng-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@yuneng-berri
yuneng-berri enabled auto-merge (squash) August 23, 2026 05:37
@yuneng-berri
yuneng-berri merged commit 5b1c142 into litellm_internal_staging Aug 24, 2026
67 of 68 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_/repo-autofix-feasibility-648801 branch August 24, 2026 17:12
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.

4 participants