[BUG] Plugin manager never reclaims its staging clones — ~/.claude/plugins/cache/temp_* grows without bound (1318 dirs / ~8 GB in 8 days)
What happened
The plugin manager leaves its staging clones behind in ~/.claude/plugins/cache/ after marketplace operations complete. They are never reclaimed, so they accumulate until the volume fills.
On this machine they grew to 1318 orphaned directories (~8.0 GB) over 8 days and contributed to a full-disk condition (0 bytes free on the data volume).
Where
~/.claude/plugins/cache/ — alongside the real, versioned installs:
~/.claude/plugins/cache/
├── claude-plugins-official/… ← real install (correct, served from here)
├── temp_git_1784761345113_n8wa6i/ ← orphan
├── temp_subdir_1784761342562_wgulhd.clone/ ← orphan
└── temp_github_…/ ← orphan
Three prefixes observed: temp_git_*, temp_subdir_*.clone, temp_github_*.
Naming pattern: temp_<kind>_<epoch_ms>_<rand6>.
They are full clones, not scratch files
Each orphan is a complete git working tree with .git and a valid origin:
$ ls -a ~/.claude/plugins/cache/temp_git_1784761345113_n8wa6i
. .. .editorconfig .git .github .gitignore .nvmrc …
$ git -C … remote get-url origin
https://github.com/obra/claude-session-driver.git
They are referenced by no plugin configuration — the installed plugins are served from the versioned <marketplace>/<version>/ directories, not from these.
It is a leak, not a one-time pile
Timestamps are embedded in the directory names, so the rate is directly measurable:
| Window | Orphans created |
|---|---|
| single 24 h window | 471 |
| peak hour (active use) | 48 |
| another active hour | 35 |
Seven temp_git_* clones were created within 10 milliseconds of each other
(…1345104, …1345106, …1345107, …1345109, …1345111, …1345113, …1345114),
which suggests a parallel fan-out over configured marketplaces (21 configured here).temp_subdir_* and temp_git_* appear in pairs ~20 ms apart, suggesting both survive the
same code path.
Rate works out to roughly 20–30 directories/hour during active use.
Expected
Staging directories are removed once the marketplace add/update/refresh they belong to
finishes — on the success path, not only on error paths. A stale-staging reclaim on
startup would also cover crashes and interrupted operations.
Actual
They persist indefinitely and accumulate without bound.
Possibly related
#77107 reports AV interrupting a plugin install mid-rename, leaving half-installed
state — same clone-then-rename area, but that issue is about the interrupted path while
this one reproduces on the successful path.
Environment
- Claude Code 2.1.218
- macOS (Apple Silicon, APFS)
- 21 marketplaces configured
Workaround
Deleting ~/.claude/plugins/cache/temp_* is safe once the operations that created them
have finished — they hold no installed-plugin state and every one is re-clonable from its
origin. Worth gating on age and on there being no open file handle, so an in-flight
operation is never touched:
find ~/.claude/plugins/cache -maxdepth 1 -name 'temp_*' -mmin +180
Note for anyone scripting this: the directory mtime is not a reliable age signal —
an interrupted rm -rf updates it, so a half-deleted carcass looks newly created and an
mtime-based filter will skip it forever. The epoch embedded in the directory name is the
immutable creation time and is the better signal.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗