[BUG] Desktop auto-worktree first session: plugin installed during bootstrap loads skills but never registers hooks — hooks silently fail open until restart

Open 💬 0 comments Opened Jul 6, 2026 by markdbodman

Preflight Checklist

  • [x] I have searched existing issues — #63028 is the closest, but that is the cloud-session variant where the plugin is fully inactive on first session. This report is the desktop variant with a more dangerous partial failure: plugin skills load, plugin hooks silently do not.
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

In the first session of a freshly created desktop auto-worktree, a project-scoped plugin's install for the new projectPath completes during session bootstrap after PreToolUse hook registration. Because plugin skills resolve dynamically per turn, the plugin appears fully present (skills are listed and invocable), but the plugin's hooks/hooks.json never registers for that session — so every hook the plugin ships silently does not fire.

We use plugin PreToolUse hooks as governance guards (deny/warn gates on Bash and AskUserQuestion). In the affected session type — which the desktop client creates by default when it auto-creates a worktree per session — all of those guards failed open with zero signal to the user or the agent.

Concrete instance (session e07d5d79, auto-worktree first session, 2026-07-06):

  • installed_plugins.json shows the plugin installed for the worktree's projectPath at 10:19:07.717; the session's first transcript record is 10:19:09.525 — install completed ~1.8s into bootstrap, after hooks were already registered.
  • Two Bash commands matching a plugin PreToolUse deny-matcher executed undenied, and one AskUserQuestion call that the same hook's logic provably blocks (replaying the exact recorded payload through the hook returns block: true) reached the user unblocked.
  • The same session later successfully invoked one of the plugin's skills — plugin present, hooks absent.
  • Control: in a session where the plugin was already installed for the projectPath (root clone, same day, same plugin version), identical Bash and AskUserQuestion probes were correctly denied by the plugin hooks.
  • Hooks wired in the checked-in project .claude/settings.json are immune — a settings-plane PostToolUse hook fired normally in the failing session. Only the plugin hook plane is affected.

The failure mode is worse than the plugin simply being absent: partial activation makes it look present. A user relying on plugin hooks for safety/policy enforcement has no way to notice they are off for exactly one session — the first one in every fresh worktree.

What Should Happen?

Either of:

  • (Preferred) When a plugin install completes during session bootstrap, register its hooks before the first turn (or re-run hook registration when the install lands), so a just-installed plugin is fully active — matching what already happens for its skills.
  • Or, surface a visible warning in the session ("plugin X installed mid-bootstrap; its hooks will not be active until you restart the session") so the failure is at least not silent.

Steps to Reproduce

  1. Have a project-scoped plugin enabled for a repo, providing both skills and hooks/hooks.json with a PreToolUse hook (e.g. one that denies a recognizable Bash command).
  2. In the desktop app, start a session on that repo such that a fresh auto-worktree is created for the session (the default worktree-per-session flow). The new worktree path is a new projectPath, so the plugin installs for it during session bootstrap.
  3. In that first session: plugin skills appear and work, but the PreToolUse hook never fires (the deny-probe command runs undenied).
  4. Start a second session in the same worktree: hooks now fire correctly.

Error Messages/Logs

None — that is the core of the bug. No warning is emitted; installed_plugins.json timestamps vs the transcript's first record are the only evidence of the ordering.

Claude Model

Opus

Is this a regression?

I don't know

Claude Code Version

2.1.197 (Claude Code, desktop app)

Platform

macOS (darwin 25.5.0)

Related

#63028 — same underlying install-vs-registration ordering on Claude Code on the web, but there the whole plugin is inactive and /reload-skills partially recovers; on desktop the skills side already self-heals dynamically, which masks the dead hook plane.

View original on GitHub ↗