[BUG] ~/.claude.json.tmp.<pid>.<hash> atomic-write leftovers are never reclaimed by the retention sweep

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 2 comments · opened Aug 18, 2026

What happened

Cleaning up a full disk I found four stale temp files sitting next to ~/.claude.json:

/root/.claude.json.tmp.2942327.410b0df6512e   53.1K
/root/.claude.json.tmp.4105867.e6ce7f85d31b   66.1K
/root/.claude.json.tmp.469437.07ff79270095    66.4K
/root/.claude.json.tmp.618010.1da311f03c01    66.6K

~/.claude.json itself is 67.8K, so each of these is a near-complete copy. None of the four PIDs were alive:

$ for f in /root/.claude.json.tmp.*; do
    pid=$(echo "$f" | sed -E 's/.*\.tmp\.([0-9]+)\..*/\1/')
    kill -0 "$pid" 2>/dev/null && echo "$pid live" || echo "$pid dead"
  done
2942327 dead
4105867 dead
469437 dead
618010 dead

The <pid>.<hash> naming reads like a write-then-rename, so these look like the losing side of an atomic write when the process died before the rename landed.

Expected

The startup retention sweep reclaims them, or the next successful write of ~/.claude.json cleans up siblings whose PID is gone.

Actual

They persist indefinitely. The sweep is clearly running and working on everything else it owns — .last-cleanup was stamped today, and 0 of 570 transcripts under ~/.claude/projects are older than the 30-day default — but these files sit outside it. They're in $HOME, not in ~/.claude/ and not in a tmpdir, so nothing enumerates them.

Why it's worth fixing

The size is small per file, but it's unbounded and grows with every crash or kill, and it scales with ~/.claude.json itself. On a box with several concurrent sessions and the occasional OOM kill this accumulates quietly. kill -0 on the embedded PID makes it a cheap, safe check — a dead PID means nobody is going to rename that file.

Environment

Claude Code 2.1.220, Ubuntu 22.04.5, kernel 5.15.0-186, single ext4 root.

View original on GitHub ↗

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