beforeShellExecution hook returning ask is ignored in Auto-review mode (honoured in Allowlist and Run Everything), 3.21.16

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

A project-level beforeShellExecution hook that answers {"permission":"ask"} gets the approval prompt in Allowlist mode and in Run Everything mode (“Hook requested approval: …”). In Auto-review mode the command runs without any prompt. deny is enforced in all three modes.

Steps to Reproduce

  1. ask.ps1, a hook that always asks:
   [Console]::In.ReadToEnd() | Out-Null
   [Console]::Out.Write('{"permission":"ask","user_message":"hook asked","agent_message":"hook asked"}')
  1. .cursor/hooks.json in the project:
   { "version": 1, "hooks": { "beforeShellExecution": [
     { "command": "powershell -NoProfile -ExecutionPolicy Bypass -File C:\\path\\to\\ask.ps1" } ] } }
  1. Set Auto-Run to Auto-review and ask the agent to run echo test > t.txt.
    Expected: an approval prompt, as Run Everything shows for the same hook answer.
    Actual: no prompt; t.txt is written.

Expected Behavior

In Auto-review, the same approval prompt that Run Everything shows (“Hook requested approval”). Actual: no prompt, and t.txt is written.

Screenshots / Screen Recordings

Operating System

Windows 10/11

Version Information

Cursor 3.21.16 (8ae78e8eee1e63479c7e0504b664bc0a80c68000, x64)

For AI issues: which model did you use?

Grok 4.6 Medium (not model-specific: the hook’s answer is skipped before the command runs)

Additional Information

What I measured (a probe hook that logged each call and answered one way per trial; every prompt was declined, so a written file means it ran with no human approval):

Auto-Run mode Hook answers ask Hook answers deny
Allowlist prompt —
Auto-review no prompt, command ran (two trials) blocked
Run Everything prompt: “Hook requested approval” —

The hook is called before Cursor’s own approval in every mode (it logs a call even when the prompt is then skipped), so the answer is available in time; Auto-review appears to let its own reviewer’s decision replace the hook’s. The hook payload doesn’t include the auto-run mode either, so a hook can’t detect Auto-review and compensate.

Why it matters: hook-based guards (including the one I maintain, Termaxa) use ask for commands that need a human but shouldn’t be refused outright. In Auto-review those currently run unreviewed by a person, while the same hook in Run Everything, nominally the most permissive mode, does get a human.

Also noticed while capturing: the beforeShellExecution payload’s cwd is an empty string in 3.21.16; the project appears only in workspace_roots.

The screenshots come from my logging probe version of the same hook, which answers “probe answered ask”; it differs from the minimal ask.ps1 above only in that it logs each call.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Good repro. Until it’s fixed, the only answer from the hook that Auto-review respects is deny, so for the commands that must get a human, I’d return deny with a user_message saying “needs manual approval, run it yourself or switch to Allowlist”. Worse UX, but it fails closed instead of open.

Also +1 on putting the auto-run mode in the payload. Without it, a guard can’t even tell which of its answers will be honoured.

Hey @devdoc83, thanks for the detailed report and the comparison table!

You’re right: in Auto-review, when Auto-review itself decides a command is safe to run, the hook’s “ask” answer currently isn’t applied, so no approval prompt appears. “deny” is still enforced in every mode, as you saw. I’ve flagged this to the team.

In the meantime, two options keep a human in the loop:

  1. Use Allowlist (or Run Everything) mode, where a hook “ask” always shows the “Hook requested approval” prompt.
  2. If you need to stay in Auto-review, have the hook return “deny” for the commands that must never run without review. The agent will see the hook’s message and can ask you before retrying.

Thanks Colin, for confirming and flagging it.

Both options match what I’ve told Termaxa users: its setup check recommends Allowlist or Run Everything for Cursor, and a team that has to stay in Auto-review can switch specific rules from ask to deny.

The one change that would let a hook handle this precisely rather than bluntly: include the auto-run mode in the beforeShellExecution payload. With it, a guard could turn ask into deny only in Auto-review and leave the other two modes alone. (Smaller, while you’re in there: cwd is an empty string in that payload in 3.21.16; the project only appears in workspace_roots.)

Happy to re-run the same trials on whichever build changes this.

Thanks, and sorry for the slow reply. Your workaround is the one Colin confirmed above, and with Termaxa it works per rule today: in .termaxa/policy.yaml, change action: ask to action: deny on the rules whose commands must reach a person, with a reason that tells the agent to hand the command over (“run this yourself”).

I didn’t make that the default because the starter policy also asks about every command no rule names. In Allowlist and Run Everything those asks reach a person as intended, so denying them all would refuse ordinary work in the two modes where ask works.