[BUG] In-session /resume picker capped at 50 most-recent sessions: scroll wraps to top, search misses older sessions (CLI claude --resume unaffected)
Bug Description
The in-session /resume picker only ever loads the 50 most-recent sessions of the project. Its lazy-loading never triggers:
- Scrolling down wraps from entry 50 back to the top of the list instead of loading older sessions.
- Search only filters the loaded 50 — typing a term that matches only older sessions returns
No sessions match "…"even though those transcripts exist on disk and are perfectly valid.
The CLI picker (claude --resume run from the shell) does not have this bug: it starts with the same 50, but lazy-loads the rest as you scroll (the header total grows, e.g. of 50 → of 89, with prefetch kicking in around 25 rows down), and its search covers all sessions on disk.
This is nasty because it masquerades as data loss: in a project with ~40 sessions/month, the in-session picker's horizon lands almost exactly at "one month ago", so it looks like a 30-day retention purge. Users will suspect cleanupPeriodDays (which is in fact honored — all transcripts verified present on disk) rather than a picker display bug.
Environment
- Claude Code v2.1.197 and v2.1.198 (native installer, Linux x86_64) — both reproduce
- Project directory with 96 top-level session
.jsonlfiles (oldest 2026-04-04), all valid (parseable, containusermessages) cleanupPeriodDays: 10000set; transcripts confirmed present on disk
Steps to Reproduce
Needs a project with more than 50 sessions.
- Start an interactive session, run
/resume. Header readsResume session (1 of 50). - Press
↓repeatedly. The total never grows past 50; after the last entry the cursor wraps back to(1 of 50). - Type a search term that only matches a session older than the newest 50 →
No sessions match. - Exit, run
claude --resumefrom the shell, repeat steps 2–3 → the total grows past 50 while scrolling, the oldest sessions are reachable, and the same search term finds the old sessions.
Reproduced deterministically by driving both pickers in a scripted tmux pane (single ↓ keypresses at 250 ms intervals, screen captured every 10 presses):
# in-session /resume, v2.1.197 and v2.1.198 — identical result:
after 10 downs: Resume session (11 of 50)
after 40 downs: Resume session (41 of 50)
after 50 downs: Resume session (1 of 50) <-- wrapped, never loaded more
search "samba" (matches only 2-month-old sessions): No sessions match "samba".
# CLI `claude --resume`, same binaries, same project:
after 20 downs: Resume session (21 of 50)
after 30 downs: Resume session (31 of 89) <-- lazy-load fired
after 60 downs: Resume session (61 of 89)
search "samba": all three matching 2-month-old sessions listed.
Expected Behavior
The in-session /resume picker should lazy-load older sessions on scroll and search across all sessions on disk, matching the CLI claude --resume picker.
Actual Behavior
In-session /resume is permanently capped at the 50 most-recent sessions: scroll wraps at the boundary, search is blind to anything older.
Workaround
Exit the session and use claude --resume from the shell, or resume directly with claude --resume <session-id> (the .jsonl filename).