v2.1.220: PreToolUse Edit events not dispatched after compact/continuation (Write fires, Edit is silent)
Summary
In v2.1.220, after a compact boundary (continuation session), PreToolUse hook events for Edit tool calls are no longer dispatched to the hook command. The same hooks receive Write events normally and Edit events were received normally pre-compact (in the same session, v2.1.220).
The hook scripts themselves are not at fault — calling them directly with an Edit stdin payload correctly returns permissionDecision: deny (verified).
Reproduction
- Start a session, allow it to compact (auto/manual)
- After the compact boundary, attempt to
Edita file that is in the deny state of any PreToolUse hook (e.g.block-until-regroundor a customdeny-edit-after-compact) - The hook does NOT fire. The
Edittool itself runs and reports the tool's own error (e.g.String to replace not found). - In the same session state, attempt
Writeto a similar file. The hook DOES fire and the tool is denied as expected.
Expected
Edit PreToolUse events should dispatch to the hook after compact, just as they do in the parent session and just as Write events do in the continuation session.
Actual
Edit events are silently dropped by the dispatcher post-compact. Other mutation tools (Write, NotebookEdit) are unaffected.
Evidence
- Pre-compact: Edit tool_uses each followed by tool_result containing the hook's deny message (e.g. "compact 直後の再接地が未完了です...") → hook fired for every pre-compact Edit.
- Post-compact (after line 472 compact boundary):
Writefollowed by tool_result with the hook's deny message → hook fired for Write.Editfollowed by tool_result<tool_use_error>String to replace not found in file</tool_use_error>→ hook never fired.- Per-session
repeat-guardstate:seq: 10, keys count: 17pre-compact →keys: 0, Edit/Write entries: 0post-compact → PostToolUse received no Edit/Write dispatches in the continuation. - v2.1.220 confirmed by entrypoint data in the first 3 transcript lines.
- Hook logic verified: stdin direct invocation of the hook with Edit input returns
permissionDecision: denycorrectly. So the issue is in the dispatcher, not the hook.
Workaround
None in v2.1.220. Write continues to receive hook dispatches, so denials based on Write are still enforced. Edit-based gates are ineffective post-compact.
Environment
- Claude Code v2.1.220
- Windows 11 Pro
- Hook configuration: standard
PreToolUsematcherEdit|Write|NotebookEditwithnode script.jscommand - Compact was triggered automatically (not user-invoked)
- Same session, same v2.1.220 build
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗