[BUG] PostToolUse:EnterPlanMode hook doesn't fire for user-initiated plan mode
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
PostToolUse:EnterPlanMode hook only fires when Claude calls the EnterPlanMode tool. It does NOT fire when the user enters plan mode via:
- Shift+Tab (interactive mode toggle)
--permission-mode plan(CLI flag)
This means hooks cannot inject plan-specific context for user-initiated plan mode sessions.
What Should Happen?
PostToolUse:EnterPlanMode should fire whenever plan mode is entered, regardless of whether:
- Claude calls the
EnterPlanModetool - User presses Shift+Tab
- User starts with
--permission-mode plan
All three methods result in the same state (plan mode active), so hooks should respond to all three.
Error Messages/Logs
# Hook log shows NO entries for user-initiated plan mode sessions:
# Session cd786c7c (Shift+Tab) - no plan_template_injector entry
# Session fac43fe0 (Shift+Tab) - no plan_template_injector entry
# Session 3045ee76 (--permission-mode plan) - no plan_template_injector entry
# Only Claude-initiated plan mode fires the hook:
2025-12-28 23:13:04.708 [INFO] [plan_template_injector] starting
2025-12-28 23:13:04.709 [INFO] [plan_template_injector] plan_template_injected via PostToolUse:EnterPlanMode session=e8be406e-...
Steps to Reproduce
- Add
EnterPlanModeto your allow list in~/.claude/settings.json:
{
"permissions": {
"allow": ["EnterPlanMode", ...]
}
}
- Create a PostToolUse:EnterPlanMode hook:
{
"hooks": {
"PostToolUse": [
{
"matcher": "EnterPlanMode",
"hooks": [{ "type": "command", "command": "echo 'HOOK FIRED' >> /tmp/plan-hook.log" }]
}
]
}
}
- Test each plan mode entry method:
# Clear log
rm -f /tmp/plan-hook.log
# Test 1: Shift+Tab
claude # press Shift+Tab twice to enter plan mode, type any prompt, exit
cat /tmp/plan-hook.log # RESULT: empty - hook didn't fire
# Test 2: CLI flag
claude --permission-mode plan -p "Hello"
cat /tmp/plan-hook.log # RESULT: empty - hook didn't fire
# Test 3: Claude calls EnterPlanMode
claude -p "Please use the EnterPlanMode tool now"
cat /tmp/plan-hook.log # RESULT: "HOOK FIRED" - only this one works
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.76
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Verified Test Results
| Entry Method | PostToolUse:EnterPlanMode Fires? | Session ID Tested |
|--------------|-----------------------------------|-------------------|
| Shift+Tab | No | cd786c7c, fac43fe0 |
| --permission-mode plan | No | 3045ee76 |
| Claude calls EnterPlanMode tool | Yes | e8be406e |
Use Case
I maintain a plan template (~1,100 tokens) with formatting guidelines. I want to inject it only when plan mode is active, but:
- SessionStart: Wastes tokens on sessions that never use plan mode (~90%)
- PostToolUse:EnterPlanMode: Only fires for Claude-initiated plan mode (incomplete)
Suggested Fix
Option A: Fire PostToolUse:EnterPlanMode synthetically when user toggles plan mode
Option B: Add new PermissionModeChange hook event with matcher support:
{
"hooks": {
"PermissionModeChange": [
{ "matcher": "plan", "hooks": [...] }
]
}
}This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗