Plugin auto-update creates incomplete cache directory, blocking session hooks

Resolved 💬 3 comments Opened Mar 17, 2026 by flavio-bongiovanni Closed Mar 20, 2026

Bug description

When Claude Code auto-updates monorepo plugins (e.g., claude-plugins-official), it creates a new version directory in the plugin cache but does not always copy hook script files to the new directory. CC then resolves $CLAUDE_PLUGIN_ROOT to the newest directory (by mtime) instead of the version listed in installed_plugins.json, causing all hooks to fail with [Errno 2] No such file or directory.

This is session-blocking — when a UserPromptSubmit hook fails this way, the user cannot send any messages. The only fix is manually copying files from the old directory to the new one.

Reproduction steps

  1. Have hookify plugin installed at version 27d2b86d72da
  2. Wait for CC to auto-update the monorepo — it creates ~/.claude/plugins/cache/claude-plugins-official/hookify/2cd88e7947b7/
  3. The new directory is created with partial structure — hooks/ directory exists but Python files (stop.py, userpromptsubmit.py, etc.) are missing
  4. installed_plugins.json still says version: "27d2b86d72da" (old, working version)
  5. CC resolves $CLAUDE_PLUGIN_ROOT to 2cd88e7947b7 (the new, incomplete directory)
  6. All hooks fail:
python3: can't open file '/home/user/.claude/plugins/cache/claude-plugins-official/hookify/2cd88e7947b7/hooks/stop.py': [Errno 2] No such file or directory
  1. UserPromptSubmit hook blocks — user cannot interact with Claude

Evidence

# installed_plugins.json says old version:
hookify: installed=27d2b86d72da  updated=2026-01-30

# But CC created new dir and resolves CLAUDE_PLUGIN_ROOT there:
~/.claude/plugins/cache/claude-plugins-official/hookify/2cd88e7947b7/  (Birth: 2026-03-16 23:47)

# Old dir has all files:
27d2b86d72da/hooks/stop.py               ✓ exists (Jan 29)
27d2b86d72da/hooks/userpromptsubmit.py    ✓ exists (Jan 29)

# New dir was missing them:
2cd88e7947b7/hooks/stop.py               ✗ missing until manual copy
2cd88e7947b7/hooks/userpromptsubmit.py    ✗ missing until manual copy

Same issue affected security-guidance plugin (also has hooks/ directory).

6 other monorepo plugins had the same version divergence (installed_plugins.json says 27d2b86d72da, cache has 2cd88e7947b7) but were not affected because they don't have hook scripts.

Root causes (two compounding issues)

  1. Non-atomic plugin update: CC creates the new version directory with partial content. Hook script files are not always included in the initial sync.
  1. Version resolution mismatch: CC resolves $CLAUDE_PLUGIN_ROOT to the newest directory in the cache (by mtime), not the version declared in installed_plugins.json. This means a half-written update directory immediately becomes the active plugin root.

Impact

  • Session-blocking: UserPromptSubmit hook failure prevents all user interaction
  • Silent: No warning before the session breaks — user discovers it when they can't type
  • Non-technical users: The only fix (copying files between cache directories) requires terminal knowledge the average user doesn't have
  • Broad surface: Any plugin with hooks/ scripts is at risk during monorepo auto-updates

Suggested fix

  • $CLAUDE_PLUGIN_ROOT should resolve to the version declared in installed_plugins.json, not the newest cache directory
  • Plugin updates should be atomic: only switch the active version after all files are confirmed present
  • Hook failures should never block UserPromptSubmit — degrade gracefully instead of preventing interaction

Environment

  • Claude Code on WSL2 (Ubuntu), Linux 6.6.87.2-microsoft-standard-WSL2
  • Plugins: hookify@claude-plugins-official, security-guidance@claude-plugins-official
  • Plugin cache: ~/.claude/plugins/cache/claude-plugins-official/

View original on GitHub ↗

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