Where does the bug appear (feature/product)?
Cursor CLI
Describe the Bug
Hooks configured in .cursor/hooks.json never run in the CLI on Windows when Git Bash is
present. Instead of running, the tool call is reported to the agent as “Hook blocked”.
The command Cursor builds is PowerShell, but it is handed to bash:
--: eval: line 1: syntax error near unexpected token `&'
`$OutputEncoding = [System.Text.Encoding]::UTF8;
Get-Content -LiteralPath '...\cursor-hooks-XXXX\payload.json' -Raw |
& { $input | .cursor/hooks/observe.cmd }'
This is the same root cause confirmed in January 2026 (“Hooks use PowerShell syntax to decode
base64, which isn’t compatible with Bash”). That thread has since auto-closed with no fix
announced, and similar reports have kept appearing for eight months, so I am filing a fresh
one with CLI-specific detail.
The important part is not just “the hook does not fire”. A hook written to OBSERVE or ALLOW
silently becomes a hard DENY. And when this is fixed, calls that are currently blocked will
start passing – a silent reversal, not an error. Anyone whose setup currently looks safe
because hooks happen to fail closed will quietly lose that protection.
Steps to Reproduce
-
On Windows with Git Bash installed (SHELL points at Git Bash), create a workspace.
-
Create
WORKSPACE/.cursor/hooks.json:{ "version": 1, "hooks": { "preToolUse": [ { "command": ".cursor/hooks/observe.cmd", "timeout": 30 } ], "beforeReadFile": [ { "command": ".cursor/hooks/observe.cmd", "timeout": 30 } ] } } -
Create
WORKSPACE/.cursor/hooks/observe.cmdthat appends its stdin to a log file and
prints{"permission":"allow"}on stdout. (Any hook works – the script is never reached.) -
Put any file in the workspace, e.g.
target.py. -
Run:
cursor-agent -p --output-format text --model MODEL --trust "Read target.py" -
Observe: the hook’s log file is EMPTY (the hook never started), and the agent reports the
Read as “Hook blocked” with the bash syntax error shown above.
Control: delete hooks.json and re-run – the file is read normally.
Expected Behavior
The hook should run: the JSON payload should reach the hook script on stdin, and the hook’s
{"permission": "allow"} should let the tool call proceed.
Failing that, a hook that cannot be launched should be reported as a hook ERROR distinct from
a policy DENY, so that “the hook is broken” is not silently indistinguishable from “the hook
decided to block”.
Operating System
Windows 10/11
Version Information
CLI:
CLI Version 2026.09.02-c22c1a3
Latest 2026.09.02-c22c1a3 (up to date)
Model Cursor Grok 4.6 High Fast
Subscription Tier Team
OS win32 (x64)
Terminal unknown
Shell c:\program files\git\bin\bash.exe
For AI issues: which model did you use?
Model name: cursor-grok-4.6-medium (also reproduced with the account default, Cursor Grok 4.6 High Fast). The model is not relevant – the failure is in the hook invocation, before the model’s tool call is executed.
For AI issues: add Request ID with privacy disabled
Not available – privacy mode is enabled on this account. Happy to reproduce with privacy disabled and provide a Request ID if that would help.
Additional Information
Workarounds that do NOT help
All tried on the CLI, identical failure each time:
- .sh and .cmd hook scripts
- absolute path in “command”
cmd /c "<absolute path>"- explicit interpreter (
uv run --no-project python <absolute path>) - unsetting SHELL
Unsetting SHELL DOES change what agent about reports
(c:\program files\git\bin\bash.exe → cmd), but the hook invocation is unaffected. So the
hook’s shell selection appears to come from somewhere other than what about reports –
that may be a useful pointer.
Prior reports of the same family
- Project-level hooks fail on Windows with Git Bash due to PowerShell injection (148131, closed)
- Hook Processing Fails on Windows with Git Bash Terminal (146808)
- Project-Level Hooks Fail to Execute on Windows (144940)
- Cursor Hooks On Windows (140293)
- sessionStart plugin hook produces no output on Windows (152629)
- The cursor hooks did not execute as expected (155711)
- Tool Calls / Commands Hanging in Git Bash (156356)
Why this blocks us
We need to bound what an agent may read. permissions covers
Shell / Read / Write / WebFetch / Mcp, so Grep and Glob do not appear to be restrictable
there – we tried Grep(**) / Glob(**), a "*" catch-all, dropping --trust, and
approvalMode: “default”, and in every case the agent still read a file outside the workspace
by absolute path. Hooks look like the only remaining lever, and we verified preToolUse does
match Read, Grep and Glob – which is what makes this bug the blocker for us.
If there is an existing way to restrict Grep/Glob that we missed, we would be glad to be
corrected – that would remove our dependency on hooks entirely.
Related known issues on Windows (same family, worth fixing together)
- The hook stdin JSON is prefixed with a UTF-8 BOM, so a plain JSON.parse throws – reported
to make security hooks silently degrade to “allow”. - Extensionless hook scripts are treated as a file-open action rather than executed.
Does this stop you from using Cursor
Sometimes - I can sometimes use Cursor