STUPID-2026-0105
Claude Code's session-cleanup routine deletes any user file whose name starts with digits, mistaking it for a dead process's stale PID file
Instruction given
None — the deletion comes from Claude Code's own internal concurrentSessionCleanup() housekeeping routine, which runs automatically on session start, on autocompact, and periodically thereafter. No user command triggers it.
Expected behavior
The cleanup routine exists to remove stale `<pid>.json` lock files left behind by dead Claude Code processes in `~/.claude/sessions/`. It should only ever delete files that are actually named `<number>.json` for a PID that is confirmed not running — never a user's own files that merely happen to start with a digit.
Actual behavior
The routine lists every file in `~/.claude/sessions/`, strips a trailing `.json` if present, and calls `parseInt(name, 10)` on what's left with no check that the whole filename was numeric. JavaScript's `parseInt` reads only the leading digits it can parse and ignores the rest, so a file named like `2026-01-01_notes.md` parses as PID `2026`. If no process with that PID happens to be alive, and the platform isn't WSL (which is explicitly exempted), the file is deleted outright with `fs.unlink()` — no warning, no confirmation, and nothing logged. Because the routine reruns on every session start and autocompact, one session's cleanup pass can destroy a completely unrelated file another session left in the same directory moments earlier.
Damage
Any file a user places in `~/.claude/sessions/` with a digit-leading name — the reporter's own repro used a plain date-stamped notes file — is permanently unlinked rather than trashed, with no restore path. The bug reproduces on native Linux and macOS (WSL is the one platform explicitly skipped in the code), meaning the routine runs this way for the large majority of Claude Code's user base on every session start, autocompact, and periodic sweep — not as a one-off edge case. The reporter filed the issue with the exact vulnerable function, a minimal repro, and a one-line fix (validate the filename against `/^\d+\.json$/` before treating it as a PID file); labeled `bug`, `data-loss`, and `high-priority` by the maintainers, the issue was closed with zero comments and no visible maintainer response, fix, or explanation.
Classification
- Agent
- Claude Code
- Failure mode
- Destructive Action
- Root cause
- Logic Error
- Domain
- Other
- Source
- Github Issue
Related incidents
Get told when an agent breaks something
We document AI agent failures daily, severity-scored against a published scale. When one lands at 7.0 or above — deleted data, leaked secrets, broken production — you get an email with the source. When nothing does, you get nothing.
This database is callable over MCP — query it from inside your agent.