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
- 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
}
]
}
]
}
}
- Install the plugin and start a session
- 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
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗