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:
Feature worked in Cursor 1.7
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
- Restart Cursor completely (required for hooks.json changes)
- Open Composer or Chat
- Ask AI: “Run this command: echo TEST_MESSAGE”
- 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):
The command is blocked (permission denied)
The custom message “
This is a custom userMessage test” appears in the Cursor chat interface
User sees helpful, specific feedback about why the command was blocked
This is the documented behavior per:
- Cursor hooks documentation: Hooks | Cursor Docs
- GitButler blog post: Deep Dive into the new Cursor Hooks | Butler's Log
- Confirmed working in Cursor 1.7
Expected for agentMessage field
When a hook returns:
{
"continue": false,
"permission": "deny",
"agentMessage": "Context for the AI agent"
}
Expected Result:
The AI agent receives the custom context message
AI can use this context to understand why the operation was blocked
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
