Internal GC silently deletes non-empty session JSONL during active conversation
Summary
During an active Claude Code session, an internal garbage-collection routine silently deleted a non-empty session JSONL file (1.67 MB, 31 user messages) along with 21 other files. The file was not moved to Trash — it was hard-deleted and only recoverable via Dropbox version history.
Environment
- Claude Code version: 2.1.81
- OS: macOS (Darwin 25.3.0, MDT / UTC-6)
- Shell: zsh
Timeline (all times local MDT, 2026-03-22)
| Time | Event |
|------|-------|
| 21:34 | SessionEnd backup hook runs — rsync --delete finds all files intact |
| 22:08 | New session starts via claude -r |
| ~22:09 | Python script successfully reads fdb7be36...jsonl (1.67 MB) from ~/.claude/projects/ |
| 22:21 | iCloud backup hook runs — rsync --delete discovers files already gone from source, deletes from backup |
| 22:35 | Dropbox backup hook runs — same; Dropbox records 22 files deleted |
The file disappeared from ~/.claude/ in a ~12-minute window between a successful read and the next backup run, during an active session where no write/delete commands were issued.
Deleted files (22 total, all at same timestamp)
Recovered from Dropbox's deleted-files log:
Session JONLs (the bug):
fdb7be36-4cec-4342-a0fa-3b0e9721a34d.jsonl— 1.67 MB, 31 user messages per session-meta. A completed session from Feb 19-20.6ce739c7-10c6-4817-9733-4c32c698e23a.jsonl— 241.82 KB
Debug logs (~/.claude/debug/*.txt): 11 files with UUID names (228 B to 257 KB)
Settings backups: 4 .claude.json.backup.<epoch> files (27 KB each, from that afternoon)
Empty session directories: 4fd14dc1..., 82088d17...
PID file: 54086.json (138 B)
The batch deletion of heterogeneous file types (debug logs, session transcripts, settings backups, PID files) at the same instant suggests a single internal cleanup routine.
What was ruled out
- User commands: Every bash command in the session was read-only (verified by extracting all tool calls from the session JSONL).
- Hooks: The user's
SessionEndhooks only runrsyncbackups.PreCompacthooks only copy/export. No hook deletes session JONLs. /clean-sessionsskill: Only targets sessions with 0 user messages and moves to~/.Trash/. This session had 31 messages and was not found in Trash.- Claude Code update: No update occurred on 3/22 (versions: 2.1.79 on 3/18, 2.1.80 on 3/19, 2.1.81 on 3/20).
- Other Claude process: Another
claude -rprocess was running in the same project, butlsofshowed no JSONL files open.
Impact
- Silent data loss of a session transcript with no warning or log entry
- Hard delete (not moved to
~/.Trash/), making recovery dependent on third-party backup services - The deleted session's subdirectory (
subagents/) was preserved, leaving orphaned data
Expected behavior
- Non-empty session JONLs should never be silently deleted
- Any cleanup routine should log what it deletes (e.g., to the debug log)
- Deleted session files should be moved to Trash, not hard-deleted, consistent with how
/clean-sessionshandles empty sessions
Reproduction
Not deterministic. The affected session was ~1 month old (Feb 19-20) and had been idle since. The deletion occurred shortly after starting a new session in the same project via claude -r.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗