/resume picker does not discover session files via filesystem scan — sessions invisible despite valid .jsonl on disk (v2.1.81)
Summary
The /resume interactive picker silently omits valid session files. A manually-created, correctly-formatted .jsonl session file placed in the project directory is completely invisible to the picker — proving the picker is not scanning the filesystem for sessions despite the v2.1.30 changelog stating it was switched to "stat-based loading."
This disproportionately affects Agent Teams users, as sessions involving subagent spawning tend to be the ones missing from the picker.
Environment
- Claude Code: v2.1.81
- Platform: Linux (GitHub Codespaces, Ubuntu)
- Interface: VS Code extension terminal + standalone CLI
- Features in use: Agent Teams (experimental), plugins
Reproduction
Method 1: Create a valid session file — picker ignores it
- Create a correctly-formatted
.jsonlfile in~/.claude/projects/<project>/with valid session metadata (type, timestamp, sessionId, cwd, version fields matching existing sessions) - Set permissions to
600(matching existing sessions) - Run
/resume - Result: New file does not appear. Count unchanged.
- Run
claude --resume <session-id-from-file>directly - Result: Session loads successfully — the file is valid, just invisible to the picker.
Method 2: Observe existing sessions
- 15 valid
.jsonlsession files exist on disk /resumepicker shows only 9 (labeled "1 of 9")- All 15 files have identical ownership (
vscode:vscode), permissions (-rw-------), and valid JSON structure - All 15 are resumable via
claude --resume <id>— only the picker fails to find them
Evidence from investigation
What was ruled out
| Theory | Test | Result |
|---|---|---|
| File format/corruption | Validated JSON structure of all files | All valid |
| Metadata flags | Checked isSidechain, parentUuid, entrypoint | Identical across shown/hidden sessions |
| First message size | Measured first user message offset and size | ~2KB offset, <700B message in both groups |
| Content format | Compared block vs string content types | All use STRING format |
| Git worktrees | Removed all worktrees (single worktree remaining) | No change — still 9 of 15 |
| Subagent companion directories | Renamed all {session-id}/subagents/ dirs to .bak | No change — still 9 of 15 |
| sessions-index.json | Verified file does not exist (expected per v2.1.30 removal) | Confirmed absent |
| Manual file creation | Created new valid session file | Picker did not discover it |
strace analysis
Tracing file access during --resume shows:
~/.claude/sessions/is read (active PID registry — only contains current session)~/.claude/history.jsonlis read (prompt history)- The specific
.jsonlfile is opened by name (when given a direct ID) - No directory scan of
~/.claude/projects/<project>/occurs for session discovery
Pattern observed (correlational, not causal)
The 9 visible sessions were all created during early setup (March 9-11, v2.1.71-72) and are small (<10KB). The 6 hidden sessions were created later (March 10-24, v2.1.72-81) and are larger (500KB-3.7MB). However, file size is not the cause — the manually-created 1.3KB test file was also invisible.
This suggests the picker relies on a session registration mechanism that was functional in early versions but stopped working at some point, rather than filesystem scanning.
Impact on Agent Teams users
Sessions that spawn subagents via Agent Teams consistently have companion {session-id}/subagents/ and {session-id}/tool-results/ directories alongside their .jsonl files. Every session with these directories was invisible to the picker. While the directories themselves are not the cause (renaming them didn't help), Agent Teams sessions are the primary victims because:
- They tend to be longer-running sessions with more content
- They may have been created after whatever registration mechanism broke
- Agent Teams is the main workflow producing sessions that users would want to resume
For Agent Teams users, the resume picker is essentially non-functional — showing only old, trivial sessions while hiding all substantive work.
Workaround
claude --resume <session-id> works reliably. Session IDs can be found via:
ls -lt ~/.claude/projects/<project-dir>/*.jsonl
Related issues
- #25032 —
sessions-index.jsonnot updated (same symptom, different era) - #24729 — Sessions not indexed since v2.1.31
- #26123 — Consolidated 3 root causes (v2.1.31+)
- #30302 — Resume crashes with large subagent history
- #19995 — "No conversations found" despite files on disk
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗