[BUG] SessionStart hooks from local plugins (isLocal: true) match but don't execute

Resolved 💬 4 comments Opened Nov 19, 2025 by zerobearing2 Closed Nov 19, 2025

SessionStart hooks from locally-installed plugins are matched but never executed, even though hooks from git-sourced plugins work correctly in the same session.

Environment

  • Claude Code version: 2.0.46
  • OS: Linux (Ubuntu 6.14.0-35-generic)
  • Plugin installation method: Local directory with "source": "./" in marketplace.json

Steps to Reproduce

  1. Create a plugin with SessionStart hook defined in hooks/hooks.json:
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh"
          }
        ]
      }
    ]
  }
}
  1. Create the hook script at hooks/session-start.sh (executable with proper shebang)
  2. Define plugin in .claude-plugin/marketplace.json with "source": "./" (local installation)
  3. Install the plugin
  4. Start a new Claude session with --debug flag enabled
  5. Check debug logs

Expected Behavior

SessionStart hook should execute and its output should be injected into the session context, similar to how git-sourced plugins (like Superpowers) work.

Actual Behavior

Debug logs show the hook is matched but never executed:

2025-11-19T12:03:52.988Z [DEBUG] Loading plugin rails-ai from source: "./"
2025-11-19T12:03:52.988Z [DEBUG] Loaded hooks from standard location for plugin rails-ai: /home/$USER/Projects/rails-ai/hooks/hooks.json
2025-11-19T12:03:53.853Z [DEBUG] Getting matching hook commands for SessionStart with query: startup
2025-11-19T12:03:53.853Z [DEBUG] Found 2 hook matchers in settings
2025-11-19T12:03:53.853Z [DEBUG] Matched 2 unique hooks for query "startup" (2 before deduplication)

No execution output appears from the rails-ai hook, but the Superpowers hook (git-sourced) executes successfully and its output appears in the session context.

Comparison: Working vs. Non-Working

Working (Superpowers plugin):

  • Source: {"source":"url","url":"https://github.com/obra/superpowers.git"}
  • Install path: /home/$USER/.claude/plugins/cache/superpowers
  • In installed_plugins.json: "isLocal": false, "version": "3.4.1"
  • Hook execution: ✅ Works - output appears in session

Not Working (rails-ai plugin):

  • Source: "./"
  • Install path: /home/$USER/Projects/rails-ai/
  • In installed_plugins.json: "isLocal": true, "version": "unknown"
  • Hook execution: ❌ Fails - matched but not executed

Additional Context

  • Both plugins use identical hook JSON structure
  • Hook script executes successfully when run manually with CLAUDE_PLUGIN_ROOT environment variable set
  • Version is defined as "version": "0.3.0" in .claude-plugin/marketplace.json but shows as "unknown" in installed_plugins.json
  • This appears to be specific to local plugins (isLocal: true)

Workaround

None found. Cannot use SessionStart hooks for local plugin development.

Impact

This prevents testing SessionStart hooks during local plugin development, requiring publishing to git and reinstalling from a remote source to test hook functionality.

View original on GitHub ↗

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