Hook ASK output not stopping agent

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Hooks with an output of ASK are supposed to stop the agent from executing, for example, an MCP request, until the user approves. On version <2.2, that worked, however at some point with v2.3 change it stopped working and allows the MCP command to be executed despite showing that the output was ASK in the hook logs.

Steps to Reproduce

  1. Configure a hook to run before MCP execution that has an ask output. Example in the additional information section below.
  2. Ask the agent to execute an MCP command that should trigger the hook.
  3. Hook logs show the hook ran with an output of “ask”, but the MCP command was executed without user intervention.

Expected Behavior

When the hook output is ASK, the MCP command should not execute and the agent should stop until the user responds.

Screenshots / Screen Recordings

Operating System

MacOS

Current Cursor Version (Menu → About Cursor → Copy)

Version: 2.3.37
VSCode Version: 1.105.1
Commit: 6e2aa94f015240b4d1c7e5410b89593f9f53fef0
Date: 2026-01-15T06:56:06.990Z
Electron: 37.7.0
Chromium: 138.0.7204.251
Node.js: 22.20.0
V8: 13.8.258.32-electron.0
OS: Darwin arm64 25.2.0

For AI issues: which model did you use?

Composer 1

For AI issues: add Request ID with privacy disabled

7ba3469b-48ea-48e5-808e-f998bbd4fe7e

Additional Information

Hook config:
#!/bin/bash
INPUT=“$(cat)”

Patterns for dangerous SQL operations that modify data

Blocks DDL and DML operations, allows SELECT and LIST operations

Erring on the side of caution - block if dangerous terms appear anywhere in input

Exception: filter out “created_at” to avoid false positives (replace with placeholder that won’t match patterns)

FILTERED_INPUT=$(echo “$INPUT” | sed ‘s/created_at/timestamp_column/gi’)
DANGEROUS_SQL_PATTERNS=“delete|drop|truncate|insert|update|alter|create|rename|merge|replace|copy|bulk|grant|revoke|call|analyze|reindex|cluster|refresh.*materialized.*view|vacuum.*full|lock.*table|optimize.*table|repair.*table|flush|load.*data|import|remove.*extension|set.*role|set.*session.*authorization|explain.*analyze”

if echo “$FILTERED_INPUT” | tr ‘[:upper:]’ ‘[:lower:]’ | grep -Eiq “$DANGEROUS_SQL_PATTERNS”; then
cat <<JSON
{ “permission”: “ask”,
“userMessage”: “Potentially destructive SQL operation detected. This may modify or delete data. Proceed?”,
“agentMessage”: “Risk gate: confirm destructive SQL action.” }
JSON
else
echo ‘{ “permission”: “allow” }’
fi

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

1 Like

Hey, thanks for the report. I can see in the screenshot that the hook returns ASK, but the MCP commands run without waiting for confirmation.

This looks like a regression in hook permission handling. We had similar issues with hooks in previous versions, like userMessage and agentMessage being ignored in v2.0.x.

I’m escalating this to the dev team. The Request ID is already in the report, so that should help us track it down.

Confirmed still occurring in 2.4.5

seeing same exact issue:

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

When a beforeShellExecution hook returns permission: "ask", the command executes immediately without prompting the user for approval.

The allow and deny permissions work correctly - only ask is broken.

Permission Expected Actual Status
"allow" Command runs Command runs :white_check_mark: Works
"deny" Command blocked Command blocked :white_check_mark: Works
"ask" User prompted Command runs (no prompt) :cross_mark: Broken

Environment:

  • Platform: Linux (Remote SSH)
  • Broken Version: 2.4.21
  • Working Version: 2.1.50 (regression)

The Hooks panel in Cursor Settings shows the hook correctly returned “ASK” (see attached screenshot), confirming Cursor receives the response but ignores it.

Steps to Reproduce

  1. Create .cursor/hooks.json:
{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      {"command": "python3 .cursor/test_hook.py"}
    ]
  }
}
  1. Create .cursor/test_hook.py:
import json
import sys

payload = json.load(sys.stdin)
cmd = payload.get("command", "")

if cmd.startswith("rm"):
    print(json.dumps({
        "permission": "ask",
        "user_message": "Dangerous command needs approval",
        "agent_message": "Please approve this rm command"
    }))
else:
    print(json.dumps({"permission": "allow"}))
  1. Reload Cursor window
  2. Have the agent execute: rm /tmp/testfile.txt

Expected Behavior

When the hook returns permission: "ask", Cursor should display a prompt allowing the user to approve or deny the command before it runs.

Actual behavior: The command runs immediately without any user prompt.

Note: Changing "ask" to "deny" correctly blocks the command, confirming the hook is working - only the "ask" permission is broken.

Screenshots / Screen Recordings

Operating System

MacOS

Version Information

Version: 2.4.21 (Universal)
VSCode Version: 1.105.1
Commit: dc8361355d709f306d5159635a677a571b277bc0
Date: 2026-01-22T16:57:59.675Z
Build Type: Stable
Release Track: Default
Electron: 39.2.7
Chromium: 142.0.7444.235
Node.js: 22.21.1
V8: 14.2.231.21-electron.0
OS: Darwin x64 24.6.0

For AI issues: which model did you use?

Claude-4.5-opus-high

Does this stop you from using Cursor

No - Cursor works, but with this issue

1 Like

common team! this should be easy!