Skip to content

fix(proxy): add team_member_budget_duration to NewTeamRequest#23484

Merged
yuneng-jiang merged 2 commits intoBerriAI:mainfrom
michelligabriele:fix/team-member-budget-duration-on-create
Mar 20, 2026
Merged

fix(proxy): add team_member_budget_duration to NewTeamRequest#23484
yuneng-jiang merged 2 commits intoBerriAI:mainfrom
michelligabriele:fix/team-member-budget-duration-on-create

Conversation

@michelligabriele
Copy link
Copy Markdown
Contributor

NewTeamRequest was missing the team_member_budget_duration field, causing Pydantic to silently drop the value when creating a team via POST /team/new. The template budget row was created without budget_duration or budget_reset_at, so the ResetBudgetJob never found it and team member spend was never reset.

Add the field to NewTeamRequest and pass it through to should_create_budget and create_team_member_budget_table in the new_team handler (matching the existing update_team path which already works correctly).

Fixes #16057

Relevant issues

Fixes #16057

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

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

  • litellm/proxy/_types.py: Added team_member_budget_duration: Optional[str] = None to NewTeamRequest — the field was present on UpdateTeamRequest but missing from NewTeamRequest, causing Pydantic to silently drop it at team creation.
  • litellm/proxy/management_endpoints/team_endpoints.py: Pass data.team_member_budget_duration to TeamMemberBudgetHandler.should_create_budget() and TeamMemberBudgetHandler.create_team_member_budget_table() in the new_team handler — matching the existing update_team handler which already passes it correctly.
  • tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py: Added 2 tests:
    • test_new_team_request_accepts_team_member_budget_duration — verifies the field is not silently dropped
    • test_create_team_member_budget_table_with_duration — verifies budget_duration is passed through to the new_budget call, resulting in a budget row with budget_duration and budget_reset_at set

NewTeamRequest was missing the team_member_budget_duration field,
causing Pydantic to silently drop the value when creating a team via
POST /team/new. The template budget row was created without
budget_duration or budget_reset_at, so the ResetBudgetJob never
found it and team member spend was never reset.

Add the field to NewTeamRequest and pass it through to
should_create_budget and create_team_member_budget_table in the
new_team handler (matching the existing update_team path which
already works correctly).

Fixes BerriAI#16057
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Mar 20, 2026 6:49pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR fixes a bug where team_member_budget_duration was silently dropped by Pydantic when creating a team via POST /team/new, because the field existed on UpdateTeamRequest but was missing from NewTeamRequest. As a result, the ResetBudgetJob never found the budget row and team member spend was never reset.

Changes:

  • litellm/proxy/_types.py: Added team_member_budget_duration: Optional[str] = None to NewTeamRequest, making it consistent with UpdateTeamRequest.
  • litellm/proxy/management_endpoints/team_endpoints.py: Passes data.team_member_budget_duration to TeamMemberBudgetHandler.should_create_budget() and TeamMemberBudgetHandler.create_team_member_budget_table() in the new_team handler — mirroring the already-correct update_team path.
  • tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py: Two new mock-only unit tests verifying: (1) Pydantic no longer drops the field, and (2) budget_duration is correctly forwarded to the new_budget call.

The fix is minimal and surgical — it threads the missing field through the existing handler signatures that already supported it. The _clean_team_member_fields helper already removes team_member_budget_duration from the team dict before DB persistence, so no downstream schema issues are introduced.

Confidence Score: 5/5

  • This PR is safe to merge — it's a minimal, well-tested additive fix with no backwards-incompatible changes.
  • The change is a single missing field addition plus two call-site wires to an already-existing handler. The update_team path served as the reference implementation and the new code is structurally identical to it. Both new tests use mocks only (satisfying the tests/test_litellm/ no-network-calls rule), and the pre-existing _clean_team_member_fields already handles removing the field before DB writes.
  • No files require special attention.

Important Files Changed

Filename Overview
litellm/proxy/_types.py Added team_member_budget_duration: Optional[str] = None to NewTeamRequest, matching the field already present on UpdateTeamRequest. Correct and minimal change.
litellm/proxy/management_endpoints/team_endpoints.py Passes data.team_member_budget_duration to should_create_budget and create_team_member_budget_table in the new_team handler — directly mirrors the already-working update_team path. The field is also cleaned up via the pre-existing _clean_team_member_fields before persisting the team record.
tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py Two new unit tests: one verifies field is not silently dropped by Pydantic, the other verifies budget_duration is forwarded to new_budget. Both use only mocks — no real network calls — satisfying the test folder policy.

Sequence Diagram

sequenceDiagram
    participant Client
    participant new_team as POST /team/new
    participant Handler as TeamMemberBudgetHandler
    participant BudgetEndpoint as budget_management_endpoints.new_budget
    participant DB as Database

    Client->>new_team: NewTeamRequest(team_member_budget_duration="30d", ...)
    new_team->>Handler: should_create_budget(team_member_budget_duration="30d")
    Handler-->>new_team: True
    new_team->>Handler: create_team_member_budget_table(team_member_budget_duration="30d")
    Handler->>BudgetEndpoint: new_budget(BudgetNewRequest(budget_duration="30d", ...))
    BudgetEndpoint->>DB: INSERT LiteLLM_BudgetTable(budget_duration="30d", budget_reset_at=...)
    DB-->>BudgetEndpoint: budget row
    BudgetEndpoint-->>Handler: budget_id
    Handler-->>new_team: data_json with metadata.team_member_budget_id
    new_team->>DB: INSERT LiteLLM_TeamTable(...)
    DB-->>new_team: team record
    new_team-->>Client: 200 OK team response
Loading

Last reviewed commit: "Merge branch 'main' ..."

@yuneng-jiang yuneng-jiang self-requested a review March 20, 2026 18:48
Copy link
Copy Markdown
Contributor

@yuneng-jiang yuneng-jiang left a comment

Choose a reason for hiding this comment

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

lgtm

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq bot commented Mar 20, 2026

Merging this PR will not alter performance

✅ 16 untouched benchmarks


Comparing michelligabriele:fix/team-member-budget-duration-on-create (f884e4a) with main (d7c419b)

Open in CodSpeed

@yuneng-jiang yuneng-jiang merged commit c6ffda9 into BerriAI:main Mar 20, 2026
39 checks passed
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.

[Bug]: internal-exploration workflow - spent team member budget doesn't get reset after budget_duration

2 participants