Skip to content

fix(auth): cache team member default budget as a typed model (LIT-5311) - #37695

Merged
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
devin/lit-5311-team-member-default-budget-redis-cache-write-fails-datetime
Aug 20, 2026
Merged

yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
devin/lit-5311-team-member-default-budget-redis-cache-write-fails-datetime

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Team member default budget never lands in Redis
  • Redis write fails on raw datetime columns
  • Error line repeats in logs, every pod re-queries DB

How it solves it:

  • Cache a validated LiteLLM_BudgetTable, not the raw row
  • Pass model_type on both read and write

User Flow

Before: a team admin with Redis-backed auth caching sees a recurring cache error, and every pod keeps hitting the database for the team's per-member budget

  1. The admin runs the proxy with enable_redis_auth_cache: true and a Redis cache backend
  2. They send POST http://localhost:4000/team/new with "team_member_budget": 25, which comes back with a team id
  3. They mint a key for a member of that team via POST http://localhost:4000/key/generate and send a POST http://localhost:4000/v1/chat/completions with it
  4. The call succeeds, but the proxy logs LiteLLM Redis Caching: async set() - Got exception from REDIS Object of type datetime is not JSON serializable
  5. Nothing is stored in Redis for that budget, so each pod repeats the database lookup once per cache window and logs the error again

After: the same flow is quiet, and the budget is shared across pods through Redis

  1. Same setup, same team, same key
  2. They send the same POST http://localhost:4000/v1/chat/completions
  3. The call succeeds and no Redis serialization error appears in the logs
  4. Redis now holds the budget as JSON, so other pods read it from the shared cache instead of the database

Relevant issues

Linear ticket

Resolves LIT-5311

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, identical on both sides: local Redis on 6379, litellm/proxy/dev_config.yaml plus

litellm_settings:
  enable_redis_auth_cache: true
  cache: true
  cache_params:
    type: redis
    host: 127.0.0.1
    port: 6379

Team and key created once against the same database, with a real Anthropic call:

curl -s -X POST http://localhost:4000/team/new -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"team_alias":"lit5311-team","team_member_budget":25,"models":["anthropic-haiku-4-5"]}'
# -> team_id 0e225030-..., metadata {"team_member_budget_id": "team-lit5311-team-budget-0cfdc66a..."}

Before (3a31331)

  1. Mint a key for a team member and make a live call
K=$(curl -s -X POST http://localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"team_id":"0e225030-ccf2-4701-bbf1-db05763bc2e1","user_id":"lit5311-user2"}' | jq -r .key)
curl -s -X POST http://localhost:4000/v1/chat/completions -H "Authorization: Bearer $K" -H "Content-Type: application/json" \
  -d '{"model":"anthropic-haiku-4-5","messages":[{"role":"user","content":"say hi in 3 words"}]}'
{"id":"chatcmpl-08d600fc-90da-4a41-b7fe-7b6678c15287","model":"anthropic-haiku-4-5",...}
  1. The proxy log carries the reported failure
20:16:02 - LiteLLM:ERROR: redis_cache.py:762 - LiteLLM Redis Caching: async set() - Got exception from REDIS Object of type datetime is not JSON serializable, Writing value={'budget_id': 'team-lit5311-team-budget-0cfdc66ac73c44dd80df22ea170a65c0', 'max_budget': 25.0, ..., 'created_at': datetime.datetime(2026, 8, 20, 20, 15, 37, 289000, tzinfo=TzInfo(0)), ...}
  1. Redis holds nothing for that budget
redis-cli keys 'team_member_default_budget*'
(empty)

After (b85546f)

  1. Same key mint and live call
K=$(curl -s -X POST http://localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"team_id":"0e225030-ccf2-4701-bbf1-db05763bc2e1","user_id":"lit5311-user3"}' | jq -r .key)
curl -s -X POST http://localhost:4000/v1/chat/completions -H "Authorization: Bearer $K" -H "Content-Type: application/json" \
  -d '{"model":"anthropic-haiku-4-5","messages":[{"role":"user","content":"say hi in 3 words"}]}'
Hey there friend.
  1. No serialization error in the log
grep -c "Object of type datetime is not JSON serializable" litellm.log
0
  1. Redis now carries the budget as JSON
redis-cli keys 'team_member_default_budget*'
redis-cli get team_member_default_budget:team-lit5311-team-budget-0cfdc66ac73c44dd80df22ea170a65c0
team_member_default_budget:team-lit5311-team-budget-0cfdc66ac73c44dd80df22ea170a65c0
{"budget_id": "team-lit5311-team-budget-0cfdc66ac73c44dd80df22ea170a65c0", "soft_budget": null, "max_budget": 25.0, "max_parallel_requests": null, "tpm_limit": null, "rpm_limit": null, "model_max_budget": null, "budget_duration": null, "allowed_models": []}

Type

🐛 Bug Fix

Caveats (if any)

  • Redis entries now carry only user-facing budget fields

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

Link to Devin session: https://app.devin.ai/sessions/225c12d857dd4668b01f73235a1705c1
Requested by: @yassin-berriai

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes Redis-backed caching of team-member default budgets by validating database rows as LiteLLM_BudgetTable objects and using the typed cache codec on reads and writes.

  • Replaces raw budget-row caching with JSON-safe typed serialization.
  • Adds regression coverage for Redis serialization, typed cache reads, and avoiding repeated database queries.

Confidence Score: 5/5

The PR appears safe to merge, with the typed cache behavior aligned with existing cache serialization and authentication-budget patterns.

The changed path validates the database row before caching, serializes it through the typed JSON codec, and reconstructs the same budget model on reads; no concrete blocking or non-blocking defect remains.

Important Files Changed

Filename Overview
litellm/proxy/auth/auth_checks.py Uses the established typed-cache protocol for team-member default budgets, preventing raw datetime fields from reaching Redis serialization.
tests/test_litellm/proxy/auth/test_auth_checks.py Adds focused regression coverage proving JSON-safe writes, typed reads, and reuse of the cached budget without another database lookup.

Reviews (1): Last reviewed commit: "fix(auth): cache team member default bud..." | Re-trigger Greptile

@codecov

codecov Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
litellm/proxy/auth/auth_checks.py 75.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing devin/lit-5311-team-member-default-budget-redis-cache-write-fails-datetime (b85546f) with litellm_internal_staging (e07a712)

Open in CodSpeed

@tin-berri tin-berri left a comment

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.

Small, correct fix — caches the team-member default budget through UserApiKeyCache's typed model_type path instead of raw dict, so Redis gets a JSON-serializable payload instead of choking on the raw datetime columns (which silently dropped the cache write and forced every pod back to the DB on every request). Test correctly exercises the actual failure mode with a bare-json.dumps() stand-in for RedisCache rather than a permissive mock, and confirms the second call hits cache (find_unique awaited once). No auth/authz logic touched, purely a caching-layer serialization fix. CI green.

@yassin-berriai
yassin-berriai enabled auto-merge (squash) August 20, 2026 23:00
@yassin-berriai
yassin-berriai merged commit 3ea1c16 into litellm_internal_staging Aug 20, 2026
70 checks passed
@yassin-berriai
yassin-berriai deleted the devin/lit-5311-team-member-default-budget-redis-cache-write-fails-datetime branch August 20, 2026 23:00
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.

3 participants