[BUG] /resume only shows a few recent conversations, most sessions missing from picker

Resolved 💬 3 comments Opened Feb 5, 2026 by mvbmir Closed Feb 9, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The /resume picker only shows a handful of recent conversations. The vast majority of past sessions are missing from the list, making it impossible to find and resume older work. I had to manually grep through ~/.claude/projects/ JSONL files to find the session I needed, then use claude --resume <uuid> from the CLI.

Even after finding the session ID manually, the --resume CLI flag took ~14 seconds to load a conversation that only has 14 messages in its chain, because the session JSONL file had grown to 102.7MB (35,500 lines from 404 subagent runs). The interactive /resume picker is essentially unusable for finding this session.

The root cause is a combination of:

  1. /resume only enriches ~10 sessions - e1H() defaults to enriching only 10 sessions at a time, and vY1() filters out sessions where firstPrompt and customTitle are both empty. Since RY1() only reads the first/last 16KB of each file, metadata like customTitle buried deep in large files is never found, causing sessions to be silently filtered out.
  1. Subagent data bloats main session files - a session that spawns many subagents (e.g., parallel ticket work) accumulates all subagent progress/messages in the main JSONL file, making it 100MB+ even though the actual conversation is tiny.
  1. Full-file parsing with silent error swallowing - s1H() reads the entire file with readFile() and parses every line. If this fails (OOM, timeout), a bare catch {} silently returns empty results, making the session appear to not exist.

What Should Happen?

  1. /resume should show ALL past sessions for the project, not just a handful of recent ones
  2. Session metadata (customTitle, summary, tags) should be reliably displayed regardless of file size
  3. The sessions-index.json file (which already contains all metadata) should be used instead of re-scanning raw JSONL files
  4. Large session files should not take 14 seconds and 720MB RAM to load a 14-message conversation

Error Messages/Logs

No error messages shown - that's part of the problem. The bare catch {} in s1H() silently swallows all errors:

// s1H() - session parser (decompiled from v2.1.31)
async function s1H(H) {
    let messages = new Map();
    try {
        let C = await Kz.readFile(H);  // Reads ENTIRE 102MB file
        let Y = iHH(C);                // Parses all 35,500 JSON lines
        for (let w of Y)
            messages.set(w.uuid, w);    // 34,830 entries → 624MB RSS
    } catch {}                          // ← Silently swallows ALL errors including OOM
    return { messages };
}

When parsing fails silently, getLastLog() returns null, and the session is treated as "not found" with no indication of why.

Steps to Reproduce

  1. Create a session that spawns many subagents (e.g., use parallel ticket completion across 10+ tickets)
  2. Session JSONL file grows to 50-100MB+ from subagent progress data
  3. Set a custom title with /title mid-conversation (so it's in the middle of the file, not the tail)
  4. End the session
  5. Start a new session and type /resume
  6. The session is either missing from the picker entirely, or shows with an unhelpful firstPrompt like [Request interrupted by user for tool use] instead of the custom title
  7. Even if found and selected, loading takes 14+ seconds

Measured data from my session:

| Metric | Affected Session | Normal Session |
|--------|-----------------|----------------|
| File size | 102.7 MB | 0.1 - 5 MB |
| Lines to parse | 35,500 | 100 - 2,000 |
| Entries in memory | 34,830 | ~200 |
| Actual conversation chain | 14 messages | ~14 messages |
| RSS to parse | 720 MB (read twice) | ~50 MB |
| Time to resume | 14 seconds | < 1 second |
| Subagent files | 404 | 0 - 5 |

Is this a regression?

I don't know

Claude Code Version

2.1.31 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Warp

Additional Information

Technical details from source analysis (v2.1.31):

The /resume flow:

  • E61 component calls ymH() which calls DrD()MPH()frD() to scan the project directory
  • e1H() enriches only the first 10 sessions (by mtime) via vY1()RY1()
  • RY1() reads only first/last 16KB of each file to extract metadata
  • For my 102MB file, the customTitle ("Portal Facade PR Chain") is at line 22,501 (69MB from start, 33MB from end) - completely outside the 16KB windows
  • vY1() filters out sessions where both firstPrompt and customTitle are empty (returns null)
  • b2$() calls GbA()s1H() twice (once for getLastLog, once for summaries), reading the entire 102MB file twice

Suggested fixes:

  1. Use sessions-index.json for the picker instead of re-scanning JSONL files - it already has all the metadata
  2. Stream JSONL parsing or index from the end instead of readFile() on the whole thing
  3. Don't read the file twice in b2$()
  4. Replace catch {} with catch (e) { log(e) } so users know WHY a session fails to load
  5. Append metadata entries (customTitle, tag, summary) at the tail of the file so the 16KB window can find them, or duplicate them there when the file is written
  6. Store subagent progress in their own files (they already go to subagents/agent-*.jsonl) instead of the main session file

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗