[{"data":1,"prerenderedAt":955},["ShallowReactive",2],{"guide:/guides/claude-code-hook-not-firing":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"tag":10,"date":11,"body":12,"_type":949,"_id":950,"_source":951,"_file":952,"_stem":953,"_extension":954},"/guides/claude-code-hook-not-firing","guides",false,"","Your Claude Code hook is not firing: a checklist","Hooks fail quietly. Work through these eight checks in order, from the settings file Claude Code is actually reading to the exit code your command returns, and you will find it.","Hooks","2026-09-05",{"type":13,"children":14,"toc":937},"root",[15,32,37,44,49,129,150,163,169,182,187,193,205,271,292,298,319,363,369,397,454,459,514,527,533,575,588,594,599,619,624,713,726,731,737,758,770,776,781,904,909,915,920,931],{"type":16,"tag":17,"props":18,"children":19},"element","p",{},[20,23,30],{"type":21,"value":22},"text","The frustrating thing about ",{"type":16,"tag":24,"props":25,"children":27},"a",{"href":26},"/guides/claude-code-hooks",[28],{"type":21,"value":29},"Claude Code hooks",{"type":21,"value":31}," is how quiet they are when they go wrong. A hook that never runs and a hook that runs and fails look identical from where you are sitting: nothing happens, and nothing says why.",{"type":16,"tag":17,"props":33,"children":34},{},[35],{"type":21,"value":36},"Here is the order to check things in. It goes from the causes that are most common and cheapest to rule out, down to the ones you should only reach for once the rest are eliminated.",{"type":16,"tag":38,"props":39,"children":41},"h2",{"id":40},"_1-the-right-settings-file",[42],{"type":21,"value":43},"1. The right settings file",{"type":16,"tag":17,"props":45,"children":46},{},[47],{"type":21,"value":48},"Hooks can live in three places, and it is easy to edit one while Claude Code reads another:",{"type":16,"tag":50,"props":51,"children":52},"table",{},[53,72],{"type":16,"tag":54,"props":55,"children":56},"thead",{},[57],{"type":16,"tag":58,"props":59,"children":60},"tr",{},[61,67],{"type":16,"tag":62,"props":63,"children":64},"th",{},[65],{"type":21,"value":66},"File",{"type":16,"tag":62,"props":68,"children":69},{},[70],{"type":21,"value":71},"Applies to",{"type":16,"tag":73,"props":74,"children":75},"tbody",{},[76,95,112],{"type":16,"tag":58,"props":77,"children":78},{},[79,90],{"type":16,"tag":80,"props":81,"children":82},"td",{},[83],{"type":16,"tag":84,"props":85,"children":87},"code",{"className":86},[],[88],{"type":21,"value":89},"~/.claude/settings.json",{"type":16,"tag":80,"props":91,"children":92},{},[93],{"type":21,"value":94},"every session, on this machine",{"type":16,"tag":58,"props":96,"children":97},{},[98,107],{"type":16,"tag":80,"props":99,"children":100},{},[101],{"type":16,"tag":84,"props":102,"children":104},{"className":103},[],[105],{"type":21,"value":106},".claude/settings.json",{"type":16,"tag":80,"props":108,"children":109},{},[110],{"type":21,"value":111},"this project, shared through the repo",{"type":16,"tag":58,"props":113,"children":114},{},[115,124],{"type":16,"tag":80,"props":116,"children":117},{},[118],{"type":16,"tag":84,"props":119,"children":121},{"className":120},[],[122],{"type":21,"value":123},".claude/settings.local.json",{"type":16,"tag":80,"props":125,"children":126},{},[127],{"type":21,"value":128},"this project, yours only, usually gitignored",{"type":16,"tag":17,"props":130,"children":131},{},[132,134,140,142,148],{"type":21,"value":133},"If you are inside WSL, note that ",{"type":16,"tag":84,"props":135,"children":137},{"className":136},[],[138],{"type":21,"value":139},"~",{"type":21,"value":141}," means your Linux home, not ",{"type":16,"tag":84,"props":143,"children":145},{"className":144},[],[146],{"type":21,"value":147},"C:\\Users\\you",{"type":21,"value":149},". A hook written into the Windows home does nothing for a session running in Ubuntu. Two homes, two files, and they are easy to confuse.",{"type":16,"tag":17,"props":151,"children":152},{},[153,155,161],{"type":21,"value":154},"Run ",{"type":16,"tag":84,"props":156,"children":158},{"className":157},[],[159],{"type":21,"value":160},"/hooks",{"type":21,"value":162}," inside a session to see what Claude Code actually loaded. If your hook is not in that list, stop here: the rest of this page is about hooks that are loaded.",{"type":16,"tag":38,"props":164,"children":166},{"id":165},"_2-restart-the-session",[167],{"type":21,"value":168},"2. Restart the session",{"type":16,"tag":17,"props":170,"children":171},{},[172,174,180],{"type":21,"value":173},"Claude Code reads its hooks when the session starts. Edit ",{"type":16,"tag":84,"props":175,"children":177},{"className":176},[],[178],{"type":21,"value":179},"settings.json",{"type":21,"value":181}," in another window and the running session keeps using the snapshot it took at launch.",{"type":16,"tag":17,"props":183,"children":184},{},[185],{"type":21,"value":186},"This is the single most common reason a correct hook appears to do nothing. Start a fresh session before you conclude anything.",{"type":16,"tag":38,"props":188,"children":190},{"id":189},"_3-valid-json",[191],{"type":21,"value":192},"3. Valid JSON",{"type":16,"tag":17,"props":194,"children":195},{},[196,198,203],{"type":21,"value":197},"A syntax error in ",{"type":16,"tag":84,"props":199,"children":201},{"className":200},[],[202],{"type":21,"value":179},{"type":21,"value":204}," does not produce a loud complaint. A trailing comma, a smart quote pasted from a web page, an unescaped backslash in a Windows path, and the file stops parsing. Your hooks go with it.",{"type":16,"tag":206,"props":207,"children":211},"pre",{"className":208,"code":209,"language":210,"meta":7,"style":7},"language-bash shiki shiki-themes github-light github-dark","python3 -m json.tool ~/.claude/settings.json > /dev/null && echo \"valid\"\n","bash",[212],{"type":16,"tag":84,"props":213,"children":214},{"__ignoreMap":7},[215],{"type":16,"tag":216,"props":217,"children":220},"span",{"class":218,"line":219},"line",1,[221,227,233,239,244,250,255,261,266],{"type":16,"tag":216,"props":222,"children":224},{"style":223},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[225],{"type":21,"value":226},"python3",{"type":16,"tag":216,"props":228,"children":230},{"style":229},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[231],{"type":21,"value":232}," -m",{"type":16,"tag":216,"props":234,"children":236},{"style":235},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[237],{"type":21,"value":238}," json.tool",{"type":16,"tag":216,"props":240,"children":241},{"style":235},[242],{"type":21,"value":243}," ~/.claude/settings.json",{"type":16,"tag":216,"props":245,"children":247},{"style":246},"--shiki-default:#D73A49;--shiki-dark:#F97583",[248],{"type":21,"value":249}," >",{"type":16,"tag":216,"props":251,"children":252},{"style":235},[253],{"type":21,"value":254}," /dev/null",{"type":16,"tag":216,"props":256,"children":258},{"style":257},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[259],{"type":21,"value":260}," && ",{"type":16,"tag":216,"props":262,"children":263},{"style":229},[264],{"type":21,"value":265},"echo",{"type":16,"tag":216,"props":267,"children":268},{"style":235},[269],{"type":21,"value":270}," \"valid\"\n",{"type":16,"tag":17,"props":272,"children":273},{},[274,276,282,284,290],{"type":21,"value":275},"Backslashes deserve their own mention. In JSON, ",{"type":16,"tag":84,"props":277,"children":279},{"className":278},[],[280],{"type":21,"value":281},"C:\\Users\\you\\script.ps1",{"type":21,"value":283}," has to be written ",{"type":16,"tag":84,"props":285,"children":287},{"className":286},[],[288],{"type":21,"value":289},"C:\\\\Users\\\\you\\\\script.ps1",{"type":21,"value":291},", and getting that wrong is the most common way to break a Windows hook config.",{"type":16,"tag":38,"props":293,"children":295},{"id":294},"_4-the-event-name-spelled-exactly",[296],{"type":21,"value":297},"4. The event name, spelled exactly",{"type":16,"tag":17,"props":299,"children":300},{},[301,303,309,311,317],{"type":21,"value":302},"Event names are case sensitive and there is no validation. Subscribe to ",{"type":16,"tag":84,"props":304,"children":306},{"className":305},[],[307],{"type":21,"value":308},"PostToolUSE",{"type":21,"value":310}," or ",{"type":16,"tag":84,"props":312,"children":314},{"className":313},[],[315],{"type":21,"value":316},"onStop",{"type":21,"value":318}," and the entry sits in your config forever, doing nothing, with no warning that the name means nothing to anyone.",{"type":16,"tag":17,"props":320,"children":321},{},[322,324,330,332,338,340,346,348,354,355,361],{"type":21,"value":323},"Check yours against ",{"type":16,"tag":24,"props":325,"children":327},{"href":326},"/guides/claude-code-hook-events",[328],{"type":21,"value":329},"what every hook event means",{"type":21,"value":331},". The most frequent slips are ",{"type":16,"tag":84,"props":333,"children":335},{"className":334},[],[336],{"type":21,"value":337},"Stop",{"type":21,"value":339}," versus ",{"type":16,"tag":84,"props":341,"children":343},{"className":342},[],[344],{"type":21,"value":345},"SubagentStop",{"type":21,"value":347},", and ",{"type":16,"tag":84,"props":349,"children":351},{"className":350},[],[352],{"type":21,"value":353},"PostToolUse",{"type":21,"value":339},{"type":16,"tag":84,"props":356,"children":358},{"className":357},[],[359],{"type":21,"value":360},"PostToolUseFailure",{"type":21,"value":362},", which are different events and fire at different moments.",{"type":16,"tag":38,"props":364,"children":366},{"id":365},"_5-your-command-exists-from-where-the-hook-runs",[367],{"type":21,"value":368},"5. Your command exists, from where the hook runs",{"type":16,"tag":17,"props":370,"children":371},{},[372,374,380,382,388,389,395],{"type":21,"value":373},"Hooks do not get your interactive shell. No ",{"type":16,"tag":84,"props":375,"children":377},{"className":376},[],[378],{"type":21,"value":379},".bashrc",{"type":21,"value":381},", no ",{"type":16,"tag":84,"props":383,"children":385},{"className":384},[],[386],{"type":21,"value":387},".zshrc",{"type":21,"value":381},{"type":16,"tag":84,"props":390,"children":392},{"className":391},[],[393],{"type":21,"value":394},".profile",{"type":21,"value":396},". Which means:",{"type":16,"tag":398,"props":399,"children":400},"ul",{},[401,421,444],{"type":16,"tag":402,"props":403,"children":404},"li",{},[405,411,413,419],{"type":16,"tag":406,"props":407,"children":408},"strong",{},[409],{"type":21,"value":410},"Aliases do not exist.",{"type":21,"value":412}," If ",{"type":16,"tag":84,"props":414,"children":416},{"className":415},[],[417],{"type":21,"value":418},"notify",{"type":21,"value":420}," is an alias, the hook sees nothing.",{"type":16,"tag":402,"props":422,"children":423},{},[424,435,437,442],{"type":16,"tag":406,"props":425,"children":426},{},[427,433],{"type":16,"tag":84,"props":428,"children":430},{"className":429},[],[431],{"type":21,"value":432},"PATH",{"type":21,"value":434}," is smaller than yours.",{"type":21,"value":436}," A tool installed by a version manager, or anything you added to ",{"type":16,"tag":84,"props":438,"children":440},{"className":439},[],[441],{"type":21,"value":432},{"type":21,"value":443}," in your shell profile, may be unreachable.",{"type":16,"tag":402,"props":445,"children":446},{},[447,452],{"type":16,"tag":406,"props":448,"children":449},{},[450],{"type":21,"value":451},"Relative paths resolve from the session's working directory",{"type":21,"value":453},", which is not necessarily where you think.",{"type":16,"tag":17,"props":455,"children":456},{},[457],{"type":21,"value":458},"The fix is dull and reliable: absolute paths for everything.",{"type":16,"tag":206,"props":460,"children":464},{"className":461,"code":462,"language":463,"meta":7,"style":7},"language-json shiki shiki-themes github-light github-dark","{ \"type\": \"command\", \"command\": \"/usr/local/bin/terminal-notifier -message 'done'\" }\n","json",[465],{"type":16,"tag":84,"props":466,"children":467},{"__ignoreMap":7},[468],{"type":16,"tag":216,"props":469,"children":470},{"class":218,"line":219},[471,476,481,486,491,496,500,504,509],{"type":16,"tag":216,"props":472,"children":473},{"style":257},[474],{"type":21,"value":475},"{ ",{"type":16,"tag":216,"props":477,"children":478},{"style":229},[479],{"type":21,"value":480},"\"type\"",{"type":16,"tag":216,"props":482,"children":483},{"style":257},[484],{"type":21,"value":485},": ",{"type":16,"tag":216,"props":487,"children":488},{"style":235},[489],{"type":21,"value":490},"\"command\"",{"type":16,"tag":216,"props":492,"children":493},{"style":257},[494],{"type":21,"value":495},", ",{"type":16,"tag":216,"props":497,"children":498},{"style":229},[499],{"type":21,"value":490},{"type":16,"tag":216,"props":501,"children":502},{"style":257},[503],{"type":21,"value":485},{"type":16,"tag":216,"props":505,"children":506},{"style":235},[507],{"type":21,"value":508},"\"/usr/local/bin/terminal-notifier -message 'done'\"",{"type":16,"tag":216,"props":510,"children":511},{"style":257},[512],{"type":21,"value":513}," }\n",{"type":16,"tag":17,"props":515,"children":516},{},[517,519,525],{"type":21,"value":518},"Confirm the same way the hook will: ",{"type":16,"tag":84,"props":520,"children":522},{"className":521},[],[523],{"type":21,"value":524},"env -i /usr/local/bin/terminal-notifier -message test",{"type":21,"value":526}," on macOS or Linux runs it with an empty environment, which is much closer to the hook's world than your terminal is.",{"type":16,"tag":38,"props":528,"children":530},{"id":529},"_6-which-shell-got-your-command",[531],{"type":21,"value":532},"6. Which shell got your command",{"type":16,"tag":17,"props":534,"children":535},{},[536,538,544,546,552,553,559,560,566,567,573],{"type":21,"value":537},"On macOS and Linux, ",{"type":16,"tag":84,"props":539,"children":541},{"className":540},[],[542],{"type":21,"value":543},"sh -c",{"type":21,"value":545},". On Windows, Git Bash if it is installed and PowerShell if it is not, and the two disagree about a surprising number of characters: ",{"type":16,"tag":84,"props":547,"children":549},{"className":548},[],[550],{"type":21,"value":551},"@",{"type":21,"value":495},{"type":16,"tag":84,"props":554,"children":556},{"className":555},[],[557],{"type":21,"value":558},"&&",{"type":21,"value":495},{"type":16,"tag":84,"props":561,"children":563},{"className":562},[],[564],{"type":21,"value":565},"> /dev/null",{"type":21,"value":495},{"type":16,"tag":84,"props":568,"children":570},{"className":569},[],[571],{"type":21,"value":572},"$VAR",{"type":21,"value":574},". A command that parses in one is a syntax error in the other, and the failure is silent.",{"type":16,"tag":17,"props":576,"children":577},{},[578,580,586],{"type":21,"value":579},"This is common enough on Windows to deserve its own page: ",{"type":16,"tag":24,"props":581,"children":583},{"href":582},"/guides/claude-code-hooks-windows",[584],{"type":21,"value":585},"which shell actually runs your hooks on Windows",{"type":21,"value":587},".",{"type":16,"tag":38,"props":589,"children":591},{"id":590},"_7-read-the-exit-code",[592],{"type":21,"value":593},"7. Read the exit code",{"type":16,"tag":17,"props":595,"children":596},{},[597],{"type":21,"value":598},"Once you are sure the hook is loaded and the command is reachable, stop guessing and look:",{"type":16,"tag":206,"props":600,"children":602},{"className":208,"code":601,"language":210,"meta":7,"style":7},"claude --debug\n",[603],{"type":16,"tag":84,"props":604,"children":605},{"__ignoreMap":7},[606],{"type":16,"tag":216,"props":607,"children":608},{"class":218,"line":219},[609,614],{"type":16,"tag":216,"props":610,"children":611},{"style":223},[612],{"type":21,"value":613},"claude",{"type":16,"tag":216,"props":615,"children":616},{"style":229},[617],{"type":21,"value":618}," --debug\n",{"type":16,"tag":17,"props":620,"children":621},{},[622],{"type":21,"value":623},"The debug output shows each hook as it fires, with its exit code. That turns \"nothing happened\" into a number, and the number tells you where you are:",{"type":16,"tag":50,"props":625,"children":626},{},[627,643],{"type":16,"tag":54,"props":628,"children":629},{},[630],{"type":16,"tag":58,"props":631,"children":632},{},[633,638],{"type":16,"tag":62,"props":634,"children":635},{},[636],{"type":21,"value":637},"Exit code",{"type":16,"tag":62,"props":639,"children":640},{},[641],{"type":21,"value":642},"Meaning",{"type":16,"tag":73,"props":644,"children":645},{},[646,663,700],{"type":16,"tag":58,"props":647,"children":648},{},[649,658],{"type":16,"tag":80,"props":650,"children":651},{},[652],{"type":16,"tag":84,"props":653,"children":655},{"className":654},[],[656],{"type":21,"value":657},"0",{"type":16,"tag":80,"props":659,"children":660},{},[661],{"type":21,"value":662},"Ran fine. If nothing visible happened, the problem is inside your script, not in the wiring.",{"type":16,"tag":58,"props":664,"children":665},{},[666,675],{"type":16,"tag":80,"props":667,"children":668},{},[669],{"type":16,"tag":84,"props":670,"children":672},{"className":671},[],[673],{"type":21,"value":674},"2",{"type":16,"tag":80,"props":676,"children":677},{},[678,683,685,691,693,698],{"type":16,"tag":406,"props":679,"children":680},{},[681],{"type":21,"value":682},"Blocking.",{"type":21,"value":684}," On ",{"type":16,"tag":84,"props":686,"children":688},{"className":687},[],[689],{"type":21,"value":690},"PreToolUse",{"type":21,"value":692}," this stops the tool call, on ",{"type":16,"tag":84,"props":694,"children":696},{"className":695},[],[697],{"type":21,"value":337},{"type":21,"value":699}," it prevents Claude from stopping.",{"type":16,"tag":58,"props":701,"children":702},{},[703,708],{"type":16,"tag":80,"props":704,"children":705},{},[706],{"type":21,"value":707},"anything else",{"type":16,"tag":80,"props":709,"children":710},{},[711],{"type":21,"value":712},"Non-blocking error. The action continues, and your script did not do its job.",{"type":16,"tag":17,"props":714,"children":715},{},[716,718,724],{"type":21,"value":717},"Exit code 2 is worth knowing about even when you are not using it deliberately. If your command can return 2 on failure, it can block a tool call by accident. Ending a fire-and-forget hook with ",{"type":16,"tag":84,"props":719,"children":721},{"className":720},[],[722],{"type":21,"value":723},"; exit 0",{"type":21,"value":725}," removes that risk entirely.",{"type":16,"tag":17,"props":727,"children":728},{},[729],{"type":21,"value":730},"Nothing at all in the debug output means the hook is not loaded. Go back to step 1.",{"type":16,"tag":38,"props":732,"children":734},{"id":733},"_8-which-binary-is-running-you",[735],{"type":21,"value":736},"8. Which binary is running you",{"type":16,"tag":17,"props":738,"children":739},{},[740,742,748,750,756],{"type":21,"value":741},"Last, and only if everything above checks out. There is a known issue on Windows where the native installer binary (",{"type":16,"tag":84,"props":743,"children":745},{"className":744},[],[746],{"type":21,"value":747},"~/.local/bin/claude.exe",{"type":21,"value":749},") does not fire user-defined hooks, while an npm-installed ",{"type":16,"tag":84,"props":751,"children":753},{"className":752},[],[754],{"type":21,"value":755},"claude.cmd",{"type":21,"value":757}," on the same machine does. Internal callbacks still appear in the logs, so it looks like hooks work in general and yours in particular is broken.",{"type":16,"tag":17,"props":759,"children":760},{},[761,763,768],{"type":21,"value":762},"If your hooks stopped the day you changed how Claude Code was installed, check which binary is first on your ",{"type":16,"tag":84,"props":764,"children":766},{"className":765},[],[767],{"type":21,"value":432},{"type":21,"value":769}," before you rewrite anything.",{"type":16,"tag":38,"props":771,"children":773},{"id":772},"the-quickest-test-of-all",[774],{"type":21,"value":775},"The quickest test of all",{"type":16,"tag":17,"props":777,"children":778},{},[779],{"type":21,"value":780},"When you are deep in a config and no longer sure of anything, replace the hook with something that cannot fail and writes proof to disk:",{"type":16,"tag":206,"props":782,"children":784},{"className":461,"code":783,"language":463,"meta":7,"style":7},"{\n  \"hooks\": {\n    \"Stop\": [\n      { \"hooks\": [{ \"type\": \"command\", \"command\": \"echo fired >> /tmp/hook-check.txt\" }] }\n    ]\n  }\n}\n",[785],{"type":16,"tag":84,"props":786,"children":787},{"__ignoreMap":7},[788,796,810,824,877,886,895],{"type":16,"tag":216,"props":789,"children":790},{"class":218,"line":219},[791],{"type":16,"tag":216,"props":792,"children":793},{"style":257},[794],{"type":21,"value":795},"{\n",{"type":16,"tag":216,"props":797,"children":799},{"class":218,"line":798},2,[800,805],{"type":16,"tag":216,"props":801,"children":802},{"style":229},[803],{"type":21,"value":804},"  \"hooks\"",{"type":16,"tag":216,"props":806,"children":807},{"style":257},[808],{"type":21,"value":809},": {\n",{"type":16,"tag":216,"props":811,"children":813},{"class":218,"line":812},3,[814,819],{"type":16,"tag":216,"props":815,"children":816},{"style":229},[817],{"type":21,"value":818},"    \"Stop\"",{"type":16,"tag":216,"props":820,"children":821},{"style":257},[822],{"type":21,"value":823},": [\n",{"type":16,"tag":216,"props":825,"children":827},{"class":218,"line":826},4,[828,833,838,843,847,851,855,859,863,867,872],{"type":16,"tag":216,"props":829,"children":830},{"style":257},[831],{"type":21,"value":832},"      { ",{"type":16,"tag":216,"props":834,"children":835},{"style":229},[836],{"type":21,"value":837},"\"hooks\"",{"type":16,"tag":216,"props":839,"children":840},{"style":257},[841],{"type":21,"value":842},": [{ ",{"type":16,"tag":216,"props":844,"children":845},{"style":229},[846],{"type":21,"value":480},{"type":16,"tag":216,"props":848,"children":849},{"style":257},[850],{"type":21,"value":485},{"type":16,"tag":216,"props":852,"children":853},{"style":235},[854],{"type":21,"value":490},{"type":16,"tag":216,"props":856,"children":857},{"style":257},[858],{"type":21,"value":495},{"type":16,"tag":216,"props":860,"children":861},{"style":229},[862],{"type":21,"value":490},{"type":16,"tag":216,"props":864,"children":865},{"style":257},[866],{"type":21,"value":485},{"type":16,"tag":216,"props":868,"children":869},{"style":235},[870],{"type":21,"value":871},"\"echo fired >> /tmp/hook-check.txt\"",{"type":16,"tag":216,"props":873,"children":874},{"style":257},[875],{"type":21,"value":876}," }] }\n",{"type":16,"tag":216,"props":878,"children":880},{"class":218,"line":879},5,[881],{"type":16,"tag":216,"props":882,"children":883},{"style":257},[884],{"type":21,"value":885},"    ]\n",{"type":16,"tag":216,"props":887,"children":889},{"class":218,"line":888},6,[890],{"type":16,"tag":216,"props":891,"children":892},{"style":257},[893],{"type":21,"value":894},"  }\n",{"type":16,"tag":216,"props":896,"children":898},{"class":218,"line":897},7,[899],{"type":16,"tag":216,"props":900,"children":901},{"style":257},[902],{"type":21,"value":903},"}\n",{"type":16,"tag":17,"props":905,"children":906},{},[907],{"type":21,"value":908},"Restart, run a prompt, look at the file. If the line is there, the wiring is fine and your real command is the problem. If it is not, you are somewhere in steps 1 to 4, and you have saved yourself from debugging a script that was never being called.",{"type":16,"tag":38,"props":910,"children":912},{"id":911},"hooks-you-do-not-have-to-debug",[913],{"type":21,"value":914},"Hooks you do not have to debug",{"type":16,"tag":17,"props":916,"children":917},{},[918],{"type":21,"value":919},"Most people write hooks for the same reason: they walk away from a long run and want to know when it needs them. That is a lot of configuration to maintain for one question.",{"type":16,"tag":17,"props":921,"children":922},{},[923,929],{"type":16,"tag":24,"props":924,"children":926},{"href":925},"/",[927],{"type":21,"value":928},"Blooby",{"type":21,"value":930}," answers it without you writing any. It installs its hooks itself, into the platform you tell it you run Claude on, and gives every project an animated mascot that works, waits, sleeps or celebrates in step with its session. When several are running, you see which one needs you rather than reading a notification to find out.",{"type":16,"tag":932,"props":933,"children":934},"style",{},[935],{"type":21,"value":936},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":7,"searchDepth":798,"depth":798,"links":938},[939,940,941,942,943,944,945,946,947,948],{"id":40,"depth":798,"text":43},{"id":165,"depth":798,"text":168},{"id":189,"depth":798,"text":192},{"id":294,"depth":798,"text":297},{"id":365,"depth":798,"text":368},{"id":529,"depth":798,"text":532},{"id":590,"depth":798,"text":593},{"id":733,"depth":798,"text":736},{"id":772,"depth":798,"text":775},{"id":911,"depth":798,"text":914},"markdown","content:guides:claude-code-hook-not-firing.md","content","guides/claude-code-hook-not-firing.md","guides/claude-code-hook-not-firing","md",1]