[REGRESSION] Hook response fields userMessage/agentMessage ignored in v2.0.64

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

The userMessage and agentMessage fields in hook responses are completely non-functional in Cursor 2.0.64, despite working correctly in Cursor 1.7. This is a regression that breaks bidirectional communication between hooks and the Cursor interface.

Evidence of Regression

User report from production usage:

“I got this working by downgrading to version 1.7 cursor (that is why it worked for me and you). However version 2 cursor does not allow for userMessage or agentMessage to work.”

This confirms:

  • :white_check_mark: Feature worked in Cursor 1.7
  • :cross_mark: Feature broke in Cursor 2.0+
  • Users forced to downgrade to restore functionality

Impact

Current Workarounds Broken

  • GitButler blog examples don’t work
  • Documentation examples fail
  • Validation workflows require file-based communication
  • Interactive hook feedback impossible

Use Cases Affected

  • JSON validation with specific error messages
  • Git commit message validation with helpful feedback
  • Security policy violations with clear explanations
  • Custom linting with actionable fix suggestions
  • Any scenario requiring user-facing hook messages

Business Impact

  • Users must downgrade to 1.7 for working hooks
  • Cannot use latest Cursor features with hook feedback to user or agent

Steps to Reproduce

Step 1: Create test hook script

Save as ~/.cursor/hooks/test-message.sh:

#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.command // empty')

if [[ "$COMMAND" == *"TEST_MESSAGE"* ]]; then
  jq -n '{
    continue: false,
    permission: "deny",
    userMessage: "✅ This is a custom userMessage test"
  }'
  exit 0
fi

jq -n '{continue: true, permission: "allow"}'
exit 0

Make it executable:

chmod +x ~/.cursor/hooks/test-message.sh

Step 2: Configure hooks

Add to ~/.cursor/hooks.json:

{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      {"command": "~/.cursor/hooks/test-message.sh"}
    ]
  }
}

Step 3: Test in Cursor

  1. Restart Cursor completely (required for hooks.json changes)
  2. Open Composer or Chat
  3. Ask AI: “Run this command: echo TEST_MESSAGE”
  4. Observe the result

Step 4: Verify hook produces correct JSON

To verify the hook is working correctly:

printf '{"command": "echo TEST_MESSAGE"}' | bash ~/.cursor/hooks/test-message.sh | jq .

Expected output:

{
  "continue": false,
  "permission": "deny",
  "userMessage": "✅ This is a custom userMessage test"
}

The hook produces perfect JSON with the userMessage field. Cursor 2.0 ignores it.

Expected Behavior

When a hook returns this JSON:

{
  "continue": false,
  "permission": "deny",
  "userMessage": "✅ This is a custom userMessage test"
}

Expected Result (as documented and working in Cursor 1.7):

  1. :white_check_mark: The command is blocked (permission denied)
  2. :white_check_mark: The custom message “:white_check_mark: This is a custom userMessage test” appears in the Cursor chat interface
  3. :white_check_mark: User sees helpful, specific feedback about why the command was blocked

This is the documented behavior per:

Expected for agentMessage field

When a hook returns:

{
  "continue": false,
  "permission": "deny",
  "agentMessage": "Context for the AI agent"
}

Expected Result:

  • :white_check_mark: The AI agent receives the custom context message
  • :white_check_mark: AI can use this context to understand why the operation was blocked
  • :white_check_mark: Enables bidirectional communication between hooks and AI

Screenshots / Screen Recordings

Operating System

MacOS

Current Cursor Version (Menu → About Cursor → Copy)

Version: 2.0.64
VSCode Version: 1.99.3
Commit: 25412918da7e74b2686b25d62da1f01cfcd27680
Date: 2025-11-06T04:35:14.424Z
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.0.0

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the report. It looks like the issue is that your test script uses userMessage (camelCase), while the docs require snake_case: user_message and agent_message.

Your current hook output:

{
  "continue": false,
  "permission": "deny",
  "userMessage": "✅ This is a custom userMessage test"
}

It should be:

{
  "continue": false,
  "permission": "deny",
  "user_message": "✅ This is a custom user_message test"
}

Please update your hook script to use user_message and agent_message (with underscores) and test again. Also check whether permission: "deny" blocks the command - that shows the hook is being read.

If it still doesn’t work with the correct field names, share the Output → Hooks panel logs so we can see what Cursor received.

1 Like

This topic was automatically closed 22 days after the last reply. New replies are no longer allowed.