Desktop "local agent mode" plugin snapshot goes stale and never refreshes (retired skills persist, new skills missing) — survives full app restart
Environment
- Claude Desktop
1.24012.9(Code tab / "local agent mode") - macOS
26.5.2 - Plugin installed from a Git-backed marketplace with
autoUpdate: true(SHA-versioned, no explicitversioninplugin.json)
Summary
The Desktop app stages a per-session copy of each marketplace plugin's skills. That staged copy can get stuck on an old revision and is then never refreshed — not by the marketplace auto-update, not by the installed_plugins.json version bump, and not by fully quitting and relaunching the app. As a result, the Code tab keeps offering slash-commands for skills that have been renamed/removed at the source, and does not surface skills that were added.
The on-disk marketplace cache and pin are correct throughout — only the Desktop app's staged snapshot is stale.
Steps to reproduce
- Install a plugin from a Git-backed marketplace and use it in the Desktop Code tab.
- At the source, change the plugin's skill set (e.g. rename a skill
skill-old→skill-new, and add another skill). Push; let the marketplace auto-update pull the new commit. - Observe that the underlying cache is updated (see "Evidence" — cache pin now points at the new commit and contains the new skills).
- In the Desktop Code tab, the old slash-command
/skill-oldis still offered and/skill-newis unknown. - Fully quit the app (Cmd-Q) and relaunch. The stale commands persist.
Expected
After the marketplace cache updates (or at the latest on app relaunch), the Code tab should offer the current skill set: renamed/removed skills gone, added skills present.
Actual
The Code tab indefinitely reflects an old plugin revision. In my case the staged snapshot was ~24 days behind and had survived many restarts.
Evidence / apparent root cause
The app stages plugin content per session at:
~/Library/Application Support/Claude/local-agent-mode-sessions/<session-uuid>/<session-uuid>/rpm/plugin_<id>/skills/
tracked by a sibling rpm/manifest.json. Each plugin entry has an updatedAt, and some also carry updatedAtVerified: true.
- The affected plugin's entry had an old
updatedAt(~24 days prior) and noupdatedAtVerifiedflag. - A different plugin in the same manifest had
updatedAtVerified: truewith a recentupdatedAtand was correctly up to date.
So the refresh/verification path runs for some plugins but silently skips others, and relaunch resumes the same session directory and replays the stale snapshot rather than re-verifying it against the cache.
Meanwhile the sources of truth were all current and mutually consistent:
- marketplace clone
HEAD=<new-sha>(contains the new skills) ~/.claude/plugins/installed_plugins.jsonpin =<new-sha>, and the correspondingcache/.../<new-sha>/skills/contains the new skills- The stale
rpm/plugin_<id>/skills/copy contained the old skill set matching a much older commit.
A plain claude CLI session (which reads ~/.claude/plugins/cache/ directly) showed the correct, current skills the whole time — the discrepancy is specific to the Desktop staged snapshot.
Workaround
With the app fully quit, rename/remove the staging directory so it is rebuilt from the cache on next launch:
mv ~/Library/Application\ Support/Claude/local-agent-mode-sessions{,.bak}
Relaunch and open a new chat — the plugin re-stages from the current cache and the correct skills appear. (Removing just the affected rpm/plugin_<id>/ snapshot also works.)
Suggested fix
On app launch (and when the marketplace cache pin changes), re-verify each staged plugin snapshot against the current cache revision and re-stage if they differ — and ensure updatedAtVerified is set consistently for all plugins, not just some. Resuming a session should not blindly replay a stale snapshot.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗