Official-marketplace plugins get versioned by the enclosing dotfiles repo's SHA when ~/.claude is a git repo (marketplace dir ships without .git)

Status Open
Reported on v2.1.205
Maintainer reply None cached
Activity 1 comment · opened Jul 22, 2026

Environment

  • Claude Code 2.1.205, macOS (darwin 25.5.0)
  • ~/.claude is itself a git repository (a common dotfiles-sync pattern: settings.json, hooks, rules tracked; everything else ignored via whitelist .gitignore)

Summary

The claude-plugins-official marketplace directory (~/.claude/plugins/marketplaces/claude-plugins-official) is written without a .git directory. When the plugin machinery determines "the marketplace's current SHA" to version SHA-tracked plugins (e.g. frontend-design, playground), the git query runs inside that directory, git walks up the tree to the nearest enclosing repo — the user's ~/.claude dotfiles repo — and returns the dotfiles HEAD instead.

Result: every commit in the user's dotfiles repo makes SHA-versioned official plugins appear outdated. On the next reconciliation pass (any claude plugin command, or session start), Claude Code "updates" them into a new version directory under plugins/cache/claude-plugins-official/<plugin>/ named after the user's dotfiles commit, with byte-identical content. The previous dir gets an .orphaned_at marker.

Evidence

  • 9 version dirs accumulated for playground (same for frontend-design); every dir name is an exact prefix-match for a commit SHA in the user's ~/.claude dotfiles repo, and each dir's creation follows that commit's timestamp:

``
$ ls ~/.claude/plugins/cache/claude-plugins-official/playground/
01a87b6700ac 08fb44446ad5 18c705d18047 62e3fc2648f0 6558c939f19c aa3ed3b657a2 cb682c27b11c eadb1215d996 ...
$ git -C ~/.claude log --format='%h %ci' | grep -E '18c705d|01a87b6|08fb444|...'
18c705d 2026-07-20 18:47:29 # etc — all match
``

  • Oldest vs newest version dir differ only by the .orphaned_at marker (content byte-identical).
  • The marketplace dir has no repo of its own:

``
$ ls ~/.claude/plugins/marketplaces/claude-plugins-official/.git
ls: No such file or directory
$ git -C ~/.claude/plugins/marketplaces/claude-plugins-official rev-parse --show-toplevel
/Users/<user>/.claude # ← the dotfiles repo answers
``

  • installed_plugins.json registers the affected plugins at the dotfiles SHA as their version.

Reproduction

  1. git init ~/.claude (or any dotfiles setup where ~/.claude is a repo).
  2. Install frontend-design or playground from the official marketplace.
  3. Make any commit in ~/.claude.
  4. Run any claude plugin update <some-other-plugin> or start a new session.
  5. A new version dir named after the dotfiles commit SHA appears in plugins/cache, byte-identical to the previous one.

Impact

Low severity — content stays correct and updates still apply — but it produces unbounded cosmetic version churn (one ghost dir per dotfiles commit), misleading version strings in installed_plugins.json, and confusing forensics for anyone investigating plugin update behavior.

Suggested fix

Before trusting a git SHA from a marketplace directory, verify the repo boundary (git -C <dir> rev-parse --show-toplevel must equal <dir>), or record the catalog SHA at fetch time instead of querying the directory afterward. Setting GIT_CEILING_DIRECTORIES for the query, or shipping the marketplace snapshot with its own .git, would also prevent the walk-up.

Related observation

gitCommitSha in installed_plugins.json also goes stale on update: an install updated from v5.0.7 → v6.1.1 (superpowers) kept the original v5.0.7-era SHA in gitCommitSha while version/content updated correctly.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗