Hooks reference changedhooks
Nearest release: v2.1.310, published 19 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 24 Oct 2026 17:07 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 24 Oct 2026 17:37 UTC.
Upstream edited
Recorded here
Lines+13added
Lines−0removed
From line
957
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits122to this page, all time
#### PowerShell started no program ### Reference scripts by path in PowerShell hooks
The whole hunk
from line 957, old and new numbered
/
This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.
from line 957
957957blocking because Git Bash wasn't found, so only exit code 0 or 2 counts as this hook's verdict.
958958```
959959
960If the error also says `PowerShell started no program`, start with [the fixes for a `command` that is only quoted strings](#powershell-started-no-program), which PowerShell prints instead of running.
961
960962Without Git Bash, any exit code other than 0 or 2 from that hook counts as a [failure](#block-the-action-when-a-hook-fails), even when it prints JSON that doesn't deny the call. To find out why the hook failed, check the [debug log](#debug-hooks). Then pick the fix that matches your hook:
961963
962964* **The call should go ahead when the hook fails**: add [`"onFailure": "continue"`](#block-the-action-when-a-hook-fails) to the hook
from line 969
967969
968970Before v2.1.309, the message read `blocking because Git Bash wasn't found and this hook doesn't set "shell" to "powershell", so only exit code 0 or 2 counts as its verdict.`
969971
972#### PowerShell started no program
973
974A hook with this error ran in PowerShell, which prints a `command` that is only quoted strings, such as `"command": "\"C:\\Tools\\guard.exe\""`, instead of running it.
975
976* **To print text, such as JSON**: set `"shell": "powershell"`, and the hook exits 0
977* **To run a `.ps1`, `.cmd`, or `.bat` file, or a `.exe` whose path has a variable**: set `"shell": "powershell"` and put `&` before the quoted path. Leave `$HOME` as written, and spell environment variables as the [`check.ps1` example](#reference-scripts-by-path-in-powershell-hooks) spells `$env:CLAUDE_PROJECT_DIR`
978* **To run one `.exe` at a path without `$`**: remove the inner quotes from `command`, then apply the [fix for a hook that runs one `.exe`](#failed-hooks-on-windows-without-git-bash), writing `"args": []` if the program takes no arguments
979* **To run a script written for Bash**: apply the [fix for a hook written for Bash](#failed-hooks-on-windows-without-git-bash)
980
970981#### Exit code 2 behavior per event
971982
972983Exit code 2 is the way a hook signals "stop, don't do this." The effect depends on the event, because some events represent actions that can be blocked (like a tool call that hasn't happened yet) and others represent things that already happened or can't be prevented.
from line 3897
38863897
38873898Instead of executing a Bash command, prompt-based hooks:
38883899
38891. Send the hook input and your prompt to a Claude model, by default the one Claude Code uses for [background functionality](https://code.claude.com/docs/en/costs.md#background-token-usage)
38902. The LLM responds with structured JSON containing a decision
38913. Claude Code processes the decision automatically
3892
3893### Prompt hook configuration
3894
3895Set `type` to `"prompt"` and provide a `prompt` string instead of a `command`. Use the `$ARGUMENTS` placeholder to inject the hook's JSON input data into your prompt text.
3896
3897In a prompt or [agent hook](#agent-based-hooks), you can write the `prompt` as a rule about what to block or allow, such as "Block any Bash command that reads `.env` files", or as a condition that must hold, such as "All unit tests pass".
3898
3899This `Stop` hook asks the LLM to evaluate whether all tasks are complete before allowing Claude to finish:
3900
3901```json theme={null}
3902{
3903 "hooks": {
3904 "Stop": [
3905 {
3906 "hooks": [
3907 {
3908 "type": "prompt",
3909 "prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete."
3910 }
3911 ]
3912 }
3913 ]
3914 }
3915}
3916```
3917
3918| Field | Required | Description |
3919| :- | :- | :- |
3920| `type` | yes | Must be `"prompt"` |
3921| `prompt` | yes | The prompt text to send to the LLM. Use `$ARGUMENTS` as a placeholder for the hook input JSON. If `$ARGUMENTS`
39001. Send the hook input and your prompt to a Claude model, by default the one Claude Code uses for [background functionality](https://code.claude.com/docs/en/costs.md#ba
No line in this hunk matches that.