[BUG] Claude Code plugin update — stale `gitCommitSha`

Status Closed — not planned
Reported on v2.1.131
Maintainer reply None cached
Activity 7 comments · opened May 6, 2026 · closed Jun 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

After claude plugin update, the version, installPath, and lastUpdated fields in ~/.claude/plugins/installed_plugins.json correctly reflect the new release, but gitCommitSha retains its plugin install-time value. The field becomes a false witness — tools or humans inspecting it to determine "what commit is currently extracted in the cache" are misled.

This completes the third leg of an architectural cluster: writes to installed_plugins.json are inconsistent across the plugin system's distinct entry points. See Cluster context under Additional Information for the cross-references and unifying diagnosis.

What Should Happen?

After claude plugin update, all of version, installPath, and gitCommitSha should reflect the new release. Specifically, gitCommitSha should match the marketplaces clone's current HEAD — i.e., the result of git -C ~/.claude/plugins/marketplaces/<marketplace> rev-parse HEAD.

Error Messages/Logs

No errors are emitted; this is a silent metadata-staleness bug. Using this field to capture the observable post-state instead:


{
  "scope": "project",
  "projectPath": "/Users/josh/Desktop/workspace/Konjugieren",
  "installPath": "/Users/josh/.claude/plugins/cache/ios-build-verify/ios-build-verify/0.2.1",
  "version": "0.2.1",
  "installedAt": "2026-05-05T23:44:07.571Z",
  "lastUpdated": "2026-05-06T14:08:33.412Z",
  "gitCommitSha": "f1f79ca56d64a3502fb2986f9dc44c3ffbe09fef"
}


The `gitCommitSha` shown is the v0.2.0 commit. The marketplaces clone has since advanced to `52e4d6f` (v0.2.1, which is what's actually extracted in the cache at `installPath`).

Steps to Reproduce

  1. Maintain a plugin in a git repo. claude plugin install <plugin>@<marketplace> --scope project from a consumer project. Note version and gitCommitSha in installed_plugins.json.
  2. Push commits to the plugin repo, bump version in .claude-plugin/plugin.json, push.
  3. In the consumer project:

``
claude plugin marketplace update <marketplace>
claude plugin update <plugin>@<marketplace> --scope project
``

  1. Re-inspect the plugin's entry in installed_plugins.json. Observe: version, installPath, lastUpdated advance correctly; gitCommitSha is unchanged from step 1.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

unknown

Claude Code Version

2.1.131

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

Cluster context

This report is the third reported instance of one architectural pattern: writes to ~/.claude/plugins/installed_plugins.json are inconsistent across the plugin system's distinct entry points. Three distinct triggers each produce a different incomplete write:

| Trigger | Failure mode | Issue |
|---|---|---|
| Project-local marketplace startup-sync | installed_plugins.json not written at all (cache advances; metadata stays at install-time version) | #43763 |
| Marketplace "autoUpdate": true runtime promotion | installed_plugins.json not written at all (UI/skills advance; bundled hooks pinned to old installPath) | #52218 |
| Explicit /plugin update (this report) | version, installPath, lastUpdated all advance correctly; gitCommitSha retains install-time value | (this issue) |

Unifying diagnosis: the registry-write logic is not centralized. Each entry point either skips the write entirely or implements its own partial version of it. #43763's reporter pinpointed function zyA as only checking scope and projectPath; this report adds that even the path which does write most fields (explicit /plugin update) misses one of them. A clean fix consolidates the write into a single function called from all three entry points — resolving the cluster atomically rather than incrementally.

Supporting evidence for fragmentation. In a sample of 8 installed plugins on the reporting machine:

  • 5 entries record gitCommitSha, 3 do not (code-simplifier@claude-plugins-official, query@contextify, swift-lsp@claude-plugins-official).
  • 1 entry (playground@claude-plugins-official) records version: "unknown" (literal string).

These divergences are consistent with separate install pipelines emitting different field subsets — the same root cause as the three triggers above, observed in steady-state rather than in transition.

Adjacent (cache-lifecycle) cluster, for triage context. #17361, #14061, #41922, and #51536 all describe cache content/version/cleanup not converging with marketplace state. Distinct from the metadata-write cluster but reinforces the broader picture: the plugin system has multiple under-coordinated state-management paths.

Likely root cause (mechanism specific to this trigger)

The cache directory created by plugin update contains no .git subdirectory — only plugin install-created caches do. Update appears to extract via a non-git path (probably copy-from-working-tree of the marketplaces clone) rather than a git clone, so there's no natural git operation in the update flow that would produce a fresh SHA. None of the three referenced issues mentions this — it's a novel data point that explains why the explicit-update path drops gitCommitSha specifically while #43763 / #52218 drop all fields.

Suggested fix

Architectural (resolves cluster #43763 + #52218 + this issue atomically). Centralize installed_plugins.json writes into a single function. Call it from each of the four entry points that should be updating the registry:

  • /plugin install
  • /plugin update
  • Project-local marketplace startup sync (#43763's path)
  • autoUpdate runtime promotion (#52218's path)

The function reads git -C ~/.claude/plugins/marketplaces/<marketplace> rev-parse HEAD for gitCommitSha, derives version from the cache's extracted plugin.json, and updates lastUpdated from the wall clock.

Localized (resolves only this issue). At the end of /plugin update, append a single git rev-parse HEAD step that refreshes gitCommitSha. Doesn't address #43763 or #52218.

Impact
  • Debugging "is my cache on the latest commit?" by reading gitCommitSha misleads any reader (human or AI agent).
  • Telemetry / analytics that aggregate by gitCommitSha will undercount post-update versions.
  • It's the only commit-level identifier in the install record; without correctness here, the only commit check requires independently comparing the cache against the marketplaces clone.
Environment
  • Claude Code (CLI), macOS 15.x (Darwin 24.6.0)
  • Plugin: ios-build-verify@ios-build-verify v0.2.0 → v0.2.1
  • Date observed: 2026-05-06
  • (If the form has separate widgets for Claude Code Version / Platform / Operating System / Terminal/Shell / Is-this-a-regression / Last-Working-Version, fill those at submission time — values not pre-known to this draft.)

View original on GitHub ↗

7 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/14061
  2. https://github.com/anthropics/claude-code/issues/43763
  3. https://github.com/anthropics/claude-code/issues/52218

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

vermont42 · 5 months ago

Thanks for surfacing the related issues. They are related but not duplicates. This issue is the third instance of an architectural cluster the body explicitly frames:

  • #43763 — project-local marketplace startup-sync does not refresh installed_plugins.json at all (no fields update).
  • #52218 — "autoUpdate": true runtime promotion does not refresh installed_plugins.json at all (UI/skills advance, bundled hooks pinned to old installPath).
  • This issue (#56740) — explicit /plugin update correctly advances version, installPath, and lastUpdated, but leaves gitCommitSha stale. Distinct trigger, distinct failure mode (partial write vs. no write).

#14061 sits in an adjacent cluster about cache content staleness rather than metadata writes, and is cross-referenced in the body for triage context, not as a duplicate.

The unifying architectural fix — centralize the installed_plugins.json write logic into a single function called from all four entry points (/plugin install, /plugin update, project-local marketplace startup-sync, and autoUpdate runtime promotion) — closes all three atomically. See the "Cluster context" table in the body.

👎 on the auto-close: this is a distinct instance of the cluster, framed and cross-referenced as such, not a duplicate of any of the three.

erikoliver · 4 months ago

Still reproducing on Claude Code 2.1.139, macOS Darwin 25.5.0, git-sourced
marketplace (HTTPS). Adding a fresh data point that matches the cluster
diagnosis exactly:

After claude plugin marketplace update ro-marketplace against a
1-commit-behind clone, the plugin was correctly reinstalled — installPath,
version, and lastUpdated advanced — but gitCommitSha stayed pinned to the
prior install's commit:

"data-handling@ro-marketplace": [{
  "scope": "user",
  "installPath": ".../cache/ro-marketplace/data-handling/0.1.2",
  "version": "0.1.2",
  "installedAt": "2026-05-20T05:13:43.052Z",
  "lastUpdated": "2026-05-20T05:24:35.862Z",
  "gitCommitSha": "7c92113c0f27aced51af35de48eea70686baf93b"
}]

Actual clone HEAD post-update: 6399d48…. So the
claude plugin marketplace update entry point is the fourth trigger that
writes installed_plugins.json inconsistently — adding to the three already
enumerated in this issue's cluster table. Same root cause; same fix (centralize
the registry write).

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

vermont42 · 3 months ago

Still reproducing on plugin v0.3.1 — requesting reopen (this was closed as stale by automation, without triage).

The bug has actually compounded since the original report. My installed_plugins.json now has multiple entries for the same plugin where the recorded gitCommitSha matches neither the version nor the actual clone HEAD:

| version | recorded gitCommitSha | what that SHA actually is |
|---|---|---|
| 0.3.1 | f1f79ca… | stale install-time value |
| 0.3.1 | 229f3ab… | the 0.2.1 release commit |
| — | clone HEAD = e5d2b09… | the real 0.3.1 commit |

The marketplace clone is correctly at e5d2b09 (0.3.1), but no registry entry records it. So gitCommitSha is not just stale — it can be flatly wrong for the version it's attached to, which defeats any "is my cache on latest?" check and corrupts SHA-keyed telemetry.

Still part of the broader cluster (#43763, #52218): inconsistent installed_plugins.json writes across entry points. The centralized-writer fix proposed above would resolve all three. Please reopen.

JartanFTW · 3 months ago

Can confirm issue.

github-actions[bot] · 1 month ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.