[BUG] In-session /resume picker capped at 50 most-recent sessions: scroll wraps to top, search misses older sessions (CLI claude --resume unaffected)

Open 💬 0 comments Opened Jul 2, 2026 by a3k7dotmd

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 50of 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 .jsonl files (oldest 2026-04-04), all valid (parseable, contain user messages)
  • cleanupPeriodDays: 10000 set; transcripts confirmed present on disk

Steps to Reproduce

Needs a project with more than 50 sessions.

  1. Start an interactive session, run /resume. Header reads Resume session (1 of 50).
  2. Press repeatedly. The total never grows past 50; after the last entry the cursor wraps back to (1 of 50).
  3. Type a search term that only matches a session older than the newest 50 → No sessions match.
  4. Exit, run claude --resume from 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).

View original on GitHub ↗