Hook event 21 of 33

PreCompact

Runs before a manual or automatic context compaction and can block it.

Exit code veto
Exit 2 blocks. A block behaves differently by trigger. Manual shows stderr to the user, a proactive automatic block skips compaction, and a recovery block still fails the request with the underlying context-limit error.
Matchers
manual, auto
if filter
Does not apply
Docs checked
2026-08-29

Before the conversation is summarised

Your context window is filling up, and Claude Code is about to replace the conversation so far with a summary to free space. Before it does that, PreCompact runs, whether you typed /compact or the window filled on its own. The matcher filters manual or auto. The payload carries trigger and custom_instructions: the text you typed after /compact, or null when you typed none, and always null on an automatic trigger.

Blocking means three different things

Exit 2 blocks compaction. What follows depends on which of three situations you blocked. On a manual /compact, your stderr is shown to you and nothing is compacted. On a proactive automatic compaction, one that runs before the window is full, compaction is skipped and the conversation continues uncompacted. On a recovery compaction, the last resort against a context-limit error, the error surfaces and the current request fails.

Exit 0 and exit 1 allow compaction unless a top-level decision: "block" with reason stops it. terminalSequence works under the shared terminal rules. The hooks reference says systemMessage and continue are discarded on this event.

The mistake most people make first

You match auto and block, to keep Claude Code from summarising away context you still need. It works the first time: the proactive compaction is skipped and the conversation carries on in full.

Later the window fills for real. Claude Code tries a recovery compaction, your hook blocks that too, and the request fails with a context-limit error. It reads as Claude Code breaking. It is your hook. The payload carries trigger and custom_instructions and no field that says which kind of automatic compaction this is, so a hook on auto has to accept that a block can fail a request.

Match manual if what you want is a check on your own /compact.

Module 02 explains what compaction takes from the conversation, and module 09 lists this event in the blocking inventory.