Repository navigation
test(e2e): read a deleted key back as deleted, not as a 404 - #41551
Merged
Merged
Conversation
/key/info now serves a deleted key from the archive with status deleted instead of answering 404, so the delete test's convergence predicate never settled and the read timed out against a 200 it kept discarding. The predicate now waits for status deleted through the same _key_info_everywhere helper the rest of the file uses, and KeyInfo carries the status field. The chat-rejection assertion after it is unchanged, so the test still proves the key stops serving.
yuneng-berri
requested a deployment
to
e2e-changed
September 17, 2026 03:04 — with
GitHub Actions
Waiting
Contributor
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced Sep 17, 2026
Closed
Contributor
Author
|
CI red on lanes already red on main, not this diff (tests/e2e only). Most are fixed by #41527; litellm_router_testing predates the range. Details in #41553. Generated by Claude Code |
yucheng-berri
approved these changes
Sep 17, 2026
tin-berri
approved these changes
Sep 17, 2026
yuneng-berri
deleted the
litellm_cadence_319f427_key_lifecycle_delete
branch
September 17, 2026 03:48
This branch is waiting to be deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Culprit: 2bfa10b
Test: management/test_key_lifecycle_e2e.py::TestKeyLifecycle::test_delete_revokes_info_and_chat_on_every_replica
The behavior change: #41311 made
/key/infoserve a deleted key from the archive withstatus: "deleted"instead of answering 404, so a test that polled for a 404 could never settleFound by the CI cadence triage routine on the scheduled e2e build at
319f427c, https://buildkite.com/berriai-1/litellm-e2e/builds/236. cc @yassin-berriai, who requested and merged #41311TLDR
Problem this solves:
/key/infofor a 404 that no longer comesHow it solves it:
status: "deleted"instead of a 404statusfield the endpoint now returnsUser Flow
This is a test-only change, so the end user here is whoever reads the nightly e2e result
Before: the scheduled e2e run reports the key lifecycle suite red, and the message points at replica propagation rather than at the real cause
test_delete_revokes_info_and_chat_on_every_replicaspends 120s pollingGET /key/infoon every replicanever converged within 120.0s of the write (control/data-plane propagation issue), quoting a healthy HTTP 200 as the last readAfter: the same run is green, and the test now states the contract the gateway actually provides
GET /key/infoand settles as soon as every replica reports the key withstatus: "deleted"Relevant issues
Affected release
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
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@greptileaito 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
This PR changes only an e2e test, so the proof is that test running against three real gateways deployed from three different commits: the culprit's parent, the culprit, and the cadence sha. The edited test has to be red on the first and green on the other two, or the edit would be accommodating the change rather than tracking it. Each run deploys a full ephemeral stack and drives the real management routes, no mocks
Shared setup:
E2E_PATHS=management/test_key_lifecycle_e2e.py,LITELLM_SHA=44a0e16c81(this branch, carrying the edited test),GATEWAY_SHAvaried per runBefore (95abc9f, the culprit's parent)
GATEWAY_SHA=95abc9fb0b67385eec60bcebe1312a0e180e53711 failed, 5 passed in 143.79s, the one failure being this test:After (44a0e16)
Gateway at the culprit, 2bfa10b
GATEWAY_SHA=2bfa10b6d96876de8cef7696720c3aed0cf43cc4passed, the whole file greenGateway at the cadence sha, 319f427
GATEWAY_SHA=319f427c403043756917aea39cab89021a7f92e7passed, the whole file greenThe same endpoint behavior is visible by hand with curl, and #41311's own description records it:
/key/infoon a deleted key returns{"status":"deleted","key_alias":"...","deleted_at":"..."}at 200 where it used to return 404. The QA runbook below reproduces that against a local proxyType
✅ Test
Caveats (if any)
Low
KeyInfo.statusis typedstr | Nonerather than a Literal of the four statuses, matchingSpendLogRow.statusin the same file. A Literal would turn any future fifth status into a validation error on unrelated readsQA runbook
/key/inforeports it as deleted rather than pretending it never existedpython litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --use_v2_migration_resolver, master keysk-1234curl -X POST localhost:4000/model/new -H "Authorization: Bearer sk-1234" -H 'Content-Type: application/json' -d '{"model_name":"qa-key-lifecycle","litellm_params":{"model":"gpt-4o-mini","mock_response":"ok"}}'curl -X POST localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -H 'Content-Type: application/json' -d '{"models":["qa-key-lifecycle"],"key_alias":"qa-key-lifecycle"}'and keepkeyandtoken_idcurl -X POST localhost:4000/v1/chat/completions -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"model":"qa-key-lifecycle","messages":[{"role":"user","content":"hi"}]}'and expect 200curl -X POST localhost:4000/key/delete -H "Authorization: Bearer sk-1234" -H 'Content-Type: application/json' -d "{\"keys\":[\"$KEY\"]}"curl -s "localhost:4000/key/info?key=$TOKEN_ID" -H "Authorization: Bearer sk-1234" | jq '.info.status'and expect"deleted"at HTTP 200, which is what this test now waits for and what it used to expect a 404 for$KEYand expect 401, which is the assertion after the poll and is unchanged by this PRFinal Attestation
🤖 Generated with Claude Code
https://claude.ai/code/session_01XvoU8fByocGJcZMBD1CrzP
Generated by Claude Code