Hook event 22 of 33

PostCompact

Runs after Claude Code finishes a manual or automatic compaction and exposes the generated conversation summary for follow-up work.

Exit code veto
Exit code cannot block
Matchers
manual, auto
if filter
Does not apply
Docs checked
2026-08-29

After the summary exists

The conversation is already gone. Compaction has run, Claude Code has replaced it with a summary, and PostCompact fires with that summary in hand. The matcher filters manual or auto, the same split PreCompact uses. The if filter does not apply, and setting it stops the handler from running.

The payload carries trigger and compact_summary, the string compaction produced. The hooks reference gives no schema, size guarantee, or stability contract for that string beyond calling it the generated conversation summary.

Reading it, not shaping it

Compaction is done before your hook runs. No exit code changes the compacted result. On exit 2 the stderr appears to you as a hook-error notice, Claude does not see it, and the compacted conversation stands. There is no decision field. systemMessage and continue are discarded, and while valid JSON is still read on every code, none of it can undo a compaction that has finished. A hook here logs the summary, sends it somewhere, or checks it for a phrase before something downstream depends on it.

The mistake most people make first

You check the summary for the name of the branch you are working on and exit 2 when it is missing, expecting compaction to be rolled back or redone.

The compacted conversation stays. Your stderr shows to you as a hook error, and Claude continues with the summary it has, branch name or not.

If the check decides whether compaction happens, it belongs on PreCompact. If what you want is to put the branch name back in front of Claude, SessionStart fires with a compact source after every compaction, and plain stdout there becomes context.

Module 09 lists this event in its inventory, and module 18 covers compaction from the build side.