Plugin hooks for SessionEnd event are not fired

Resolved 💬 5 comments Opened Mar 12, 2026 by kok1eee Closed Apr 18, 2026

Description

SessionEnd hooks defined in a plugin's settings.json are never fired when a session ends. The same hook configuration works correctly when placed in the project's .claude/settings.local.json.

Steps to Reproduce

  1. Create a plugin with a SessionEnd hook in .claude-plugin/settings.json:
{
  "hooks": {
    "SessionEnd": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/my-hook.sh",
            "timeout": 10000
          }
        ]
      }
    ]
  }
}
  1. Install the plugin and start a session
  2. End the session (Ctrl+C or /exit)

Expected: The SessionEnd hook fires and my-hook.sh runs
Actual: The hook does not fire at all (verified by adding debug logging — no output file is generated)

Workaround

Adding the same SessionEnd hook configuration to the project-level .claude/settings.local.json works correctly. The hook fires, receives transcript_path and reason as documented.

Environment

  • Claude Code version: 2.1.74
  • OS: macOS (Darwin 25.3.0)

Notes

  • Other hook events (PreCompact, SessionStart, Stop, etc.) fire correctly from plugin settings.json
  • The issue appears to be specific to SessionEnd not being dispatched to plugin hooks
  • This may also affect WorktreeCreate/WorktreeRemove and other newer hook events, though I haven't tested those

View original on GitHub ↗

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