[BUG] Plugin manager never reclaims its staging clones — ~/.claude/plugins/cache/temp_* grows without bound (1318 dirs / ~8 GB in 8 days)

Status Fixed / completed
Reported on v2.1.218
Maintainer reply None cached
Activity 2 comments · opened Jul 22, 2026 · closed Aug 25, 2026

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.

View original on GitHub ↗

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