Skip to content

Fix IndexError in CacheOrder.pop() on empty cache#1054

Draft
lyonsno wants to merge 2 commits intoml-explore:mainfrom
lyonsno:fix-cache-order-pop-empty
Draft

Fix IndexError in CacheOrder.pop() on empty cache#1054
lyonsno wants to merge 2 commits intoml-explore:mainfrom
lyonsno:fix-cache-order-pop-empty

Conversation

@lyonsno
Copy link
Copy Markdown
Contributor

@lyonsno lyonsno commented Mar 25, 2026

Summary

  • LRUPromptCache.trim_to(n_bytes=0) can crash with IndexError if the byte-eviction loop runs after _n_bytes has drifted out of sync with the actual cache contents. The while self._n_bytes > n_bytes loop had no guard against an empty CacheOrder, so pop() could call popleft() on an empty deque.
  • Added len(self._lru) > 0 guard on the byte-eviction loop in trim_to, and an explicit empty check in CacheOrder.pop() for a clearer error if a future caller bypasses the guard.

Test plan

  • test_trim_to_zero_bytes_on_empty_cachetrim_to(n_bytes=0) on empty cache no longer raises
  • test_trim_to_zero_bytes_evicts_alltrim_to(n_bytes=0) on populated cache evicts all entries cleanly

Found during production testing on Qwen3.5-122B (M2 Ultra 128GB) while reviewing #1042.

🤖 Generated with Claude Code

`trim_to(n_bytes=0)` loops on `self._n_bytes > n_bytes` without checking
whether the CacheOrder has entries left to evict.  When both internal
deques are empty, `0 >= 0` selects the regular deque and `popleft()`
raises `IndexError`.

Guard `trim_to`'s byte-eviction loop with `len(self._lru) > 0` and add
an explicit empty check in `CacheOrder.pop()` for a clearer error
message if a caller ever bypasses the guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant