[BUG] Ref-pinned plugin marketplace is un-updatable: settings.json ref edit ignored, marketplace update fails with bare EPERM, plugin update silently reverts manual repair
Environment
- Claude Code 2.1.206 (native installer, user scope)
- macOS (Darwin 24.6.0), zsh
- Marketplace:
githubsource (brookstalley/prawduct), added ~2026-06-13 pinned to refv2.1.5
Summary
A plugin marketplace pinned to a git ref cannot be moved to a newer ref through any documented path. Three linked defects compound into a trap where the user is told everything is up to date while being permanently stranded on an old plugin version:
1. settings.json ref edits don't propagate
extraKnownMarketplaces.<name>.source.ref in ~/.claude/settings.json is not synced into ~/.claude/plugins/known_marketplaces.json for an already-known marketplace — and known_marketplaces.json is what the CLI actually obeys. Editing settings appears to work and does nothing.
2. Ref-pinned marketplaces are structurally un-updatable, and the failure is masked
The clone created for a ref-pinned marketplace is shallow with a fetch refspec covering only that one tag:
[remote "origin"]
url = git@github.com:brookstalley/prawduct.git
fetch = +refs/tags/v2.1.5:refs/tags/v2.1.5
Newer tags can never arrive through that refspec. claude plugin marketplace update <name> fails with:
error: An internal error occurred (EPERM)
— no mention of the pin, the refspec, or the underlying git/ssh failure (the remote is SSH; a Permission denied (publickey) from a spawned git appears to surface as this bare EPERM). Note the existing EPERM issues (#58241, #52435, #46830, #54053) are all Windows rename races; this is a different, macOS-reproducible path. #31678 already flags that pinned-marketplace update behavior is undocumented.
3. plugin update silently reverts manual repair and reports false success
After manually repairing the clone (HTTPS remote, refspec re-pointed to the new tag, fetch + checkout v2.3.3 — verified: HEAD at the new tag, plugin.json showing 2.3.3), running claude plugin update <plugin>@<marketplace> checked the clone back out to the old pinned tag and reported:
✔ prawduct is already at the latest version (2.1.5).
Reflog evidence:
a15c8ab HEAD@{0}: checkout: moving from e9e17011... to v2.1.5 <- performed by `claude plugin update`
e9e1701 HEAD@{1}: checkout: moving from a15c8ab... to v2.3.3 <- manual repair
a15c8ab HEAD@{2}: clone: from github.com:brookstalley/prawduct.git
The CLI destroyed the user's repair and claimed success — the worst combination for debuggability.
Working workaround (for anyone else stuck)
Edit the ref directly in ~/.claude/plugins/known_marketplaces.json, then claude plugin marketplace update <name> and claude plugin update <plugin>@<marketplace> both succeed normally.
Expected behavior
- Either propagate
extraKnownMarketplaces.source.refchanges into the plugin-managed state, or document that the settings entry is install-time-only. marketplace updateon a ref-pinned marketplace should either move the pin, or say plainly: "marketplace is pinned tov2.1.5; update the pin to receive newer versions."- Surface the underlying git error instead of a bare
EPERM. plugin updateshould never report "already at the latest version" immediately after reverting the marketplace working tree it just checked.