After opening the terminal and goes into the project repository directory, running cursor . results in the following error:
/usr/local/bin/cursor: line 20: 33419 Killed: 9
ELECTRON_RUN_AS_NODE=1 “/Applications/Cursor.app/Contents/MacOS/Cursor” “/Applications/Cursor.app/Contents/Resources/app/out/cli.js” .
Initially, Cursor showed no response and failed to launch. After some time, Cursor started opening, but it did not open the current working directory correctly.
I have already tried the following troubleshooting steps, but the issue persists:
Reinstalling Cursor
Uninstalling and re-installing the Cursor command-line tool
Deleting Cursor’s cache and configuration files
Restarting the computer
Steps to Reproduce
open project directory and type: cursor .
Cursor not responese and return an Error: /usr/local/bin/cursor: line 20: 26654 Killed: 9 ELECTRON_RUN_AS_NODE=1 “/Applications/Cursor.app/Contents/MacOS/Cursor” “/Applications/Cursor.app/Contents/Resources/app/out/cli.js” .
Operating System
MacOS
Current Cursor Version (Menu → About Cursor → Copy)
I v retry a lot of times, and find another error showed in Console, which seems different from many others:
`Sandbox: logd_helper(376) deny(1) file-read-data /Applications/Cursor.app/Contents/Resources/app/extensions/cursor-retrieval/node_modules/@anysphere/file-service/file_service.darwin-universal.node`
ls -l /usr/local/bin/cursor returns lrwxr-xr-x@ 1 mac wheel 56 12 1 18:10 /usr/local/bin/cursor -> /Applications/Cursor.app/Contents/Resources/app/bin/code
cat:
#!/usr/bin/env bash
#
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
function app_realpath() {
SOURCE=$1
while [ -h "$SOURCE" ]; do
DIR=$(dirname "$SOURCE")
SOURCE=$(readlink "$SOURCE")
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
done
SOURCE_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
echo "${SOURCE_DIR%%${SOURCE_DIR#*.app}}"
}
function use_cursor_cli() {
if [ -n "$CURSOR_CLI" ]; then
# Use the CLI found by find_cursor_cli
eval "$CURSOR_CLI" "$@"
exit $?
else
echo "Error: Cursor CLI not found. Please install Cursor properly." 1>&2
exit 1
fi
}
function find_cursor_cli() {
# Clear the output variables
CURSOR_CLI=""
CURSOR_CLI_MODE=""
# when run in remote terminal, use the remote cli
if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then
REMOTE_CLI="$(which -a 'cursor' | grep /remote-cli/)"
if [ -n "$REMOTE_CLI" ]; then
CURSOR_CLI="$REMOTE_CLI"
CURSOR_CLI_MODE="remote"
return 0
fi
fi
# Otherwise, use the electron app
APP_PATH="$(app_realpath "${BASH_SOURCE[0]}")"
if [ -z "$APP_PATH" ]; then
echo "Unable to determine app path from symlink : ${BASH_SOURCE[0]}" >&2
return 1
fi
CONTENTS="$APP_PATH/Contents"
ELECTRON="$CONTENTS/MacOS/Cursor"
CLI="$CONTENTS/Resources/app/out/cli.js"
CURSOR_CLI="ELECTRON_RUN_AS_NODE=1 \"$ELECTRON\" \"$CLI\""
CURSOR_CLI_MODE="local"
return 0
}
# Main execution
export VSCODE_NODE_OPTIONS=$NODE_OPTIONS
export VSCODE_NODE_REPL_EXTERNAL_MODULE=$NODE_REPL_EXTERNAL_MODULE
unset NODE_OPTIONS
unset NODE_REPL_EXTERNAL_MODULE
# Check if cursor-agent is blocked but user is trying to use it
if [ "$1" = "agent" ] && [ "$CURSOR_CLI_BLOCK_CURSOR_AGENT" = "true" ]; then
echo "cursor-agent is blocked in your environment due to the CURSOR_CLI_BLOCK_CURSOR_AGENT environment variable" 1>&2
echo "Please remove the block to use cursor-agent command." 1>&2
exit 1
fi
if ! find_cursor_cli && [ "$1" != "agent" ]; then
echo "Error: Cursor CLI not found. Please install Cursor properly." 1>&2
exit 1
fi
# Export variables for compatibility
# These variables are needed even in cursor-agent, to know that we are routing from 'cursor' command
if [ -n "$CURSOR_CLI" ]; then
export CURSOR_CLI
export CURSOR_CLI_MODE
fi
# Simplified routing logic
if [ "$1" = "editor" ]; then
# Route to Cursor CLI, removing the 'editor' argument
# cursor editor is equivalent to cursor, just explicitly stating that
# editor is being used (instead of agent being used)
shift
use_cursor_cli "$@"
elif [ "$1" = "agent" ] && [ "$CURSOR_CLI_BLOCK_CURSOR_AGENT" != "true" ]; then
# Route to cursor-agent
if ! command -v ~/.local/bin/cursor-agent >/dev/null 2>&1; then
echo "cursor-agent not found, installing via https://cursor.com/install ..."
curl -sS https://cursor.com/install | bash >/dev/null 2>&1
# Remove the previous log line from the terminal output
if command -v tput >/dev/null 2>&1; then
tput cuu1 && tput el
fi
# Check if installation succeeded
if ! command -v ~/.local/bin/cursor-agent >/dev/null 2>&1; then
echo "Error: Could not install cursor-agent." 1>&2
echo "Please install manually by running 'curl -sS https://cursor.com/install | bash >/dev/null'" 1>&2
echo "" 1>&2
echo "To open IDE, use 'cursor' or 'cursor editor' command." 1>&2
exit 1
fi
fi
# Check current cursor-agent version meets minimum version requirement
OUTPUT=$({ ~/.local/bin/cursor-agent --min-version=2025.10.01 status; } 2>&1)
EXIT_CODE=$?
# Update and retry if version is too old or doesn't support --min-version
if { [ "$EXIT_CODE" -eq 2 ] || { [ "$EXIT_CODE" -eq 1 ] && echo "$OUTPUT" | grep -qi "unknown option"; }; }; then
echo "cursor-agent version is outdated, updating..."
~/.local/bin/cursor-agent update >/dev/null 2>&1
# Remove the previous log line from the terminal output
if command -v tput >/dev/null 2>&1; then
tput cuu1 && tput el
fi
# Check new version to see if minimum version requirement is met
OUTPUT2=$({ ~/.local/bin/cursor-agent --min-version=2025.10.01 status; } 2>&1)
EXIT_CODE2=$?
if { [ "$EXIT_CODE2" -eq 2 ] || { [ "$EXIT_CODE2" -eq 1 ] && echo "$OUTPUT2" | grep -qi "unknown option"; }; }; then
echo "Error: cursor-agent version is too old. Please update with 'cursor-agent update'" 1>&2
exit 1
fi
fi
# Version is sufficient, run cursor-agent
export CURSOR_CLI_COMPAT=1
exec ~/.local/bin/cursor-agent "$@"
else
# Route to Cursor CLI
use_cursor_cli "$@"
fi
> spctl -a -t exec -vv /Applications/Cursor.app
/Applications/Cursor.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Hilary Stout (VDXQ22DGB9)
> xattr /Applications/Cursor.app
com.apple.macl
com.apple.quarantine
> xattr -d com.apple.quarantine /Applications/Cursor.app
> ELECTRON_RUN_AS_NODE=1 "/Applications/Cursor.app/Contents/MacOS/Cursor" "/Applications/Cursor.app/Contents/Resources/app/out/cli.js" -v
fish: Job 1, 'ELECTRON_RUN_AS_NODE=1 "/Applic…' terminated by signal SIGKILL (Forced quit)
> xattr /Applications/Cursor.app
com.apple.macl
com.apple.provenance
Then I asked LLM, got an answer:
You're very close to the root cause! Here's the current situation:
- ✅ The app is **properly notarized** (`spctl` shows `Notarized Developer ID`)
- ✅ `com.apple.quarantine` has been **successfully removed**
- ❌ But the CLI command still gets killed with `SIGKILL`
- 🔍 And now **`com.apple.provenance`** appears (not quarantine)
This indicates the issue has escalated to macOS Sonoma/Sequoia’s newer security mechanism: **Provenance Tracking**.
---
## 🔍 Core Issue: `com.apple.provenance` + `ELECTRON_RUN_AS_NODE`
In **macOS Sonoma 14.5+ and Sequoia**, Apple introduced stricter **provenance-based execution policies**:
> Even if an app is notarized, if the system cannot verify the **integrity of its runtime context** (e.g., when invoked directly from a terminal or script), it will block sensitive operations and attach the `com.apple.provenance` attribute.
And `ELECTRON_RUN_AS_NODE=1` is explicitly treated by macOS as a **high-risk operation** (it can execute arbitrary JavaScript code), thus triggering `SIGKILL`.
> 📌 Key point:
> **GUI launch (via Launch Services) ✅ Allowed**
> **Direct binary invocation from CLI ❌ Blocked**
---
## ✅ Actually Effective Solutions
### ✅ Method 1: **Launch CLI via Launch Services (Recommended)**
Avoid calling the binary directly. Instead, let the system launch it as a proper application:
```bash
# If Cursor supports a URL scheme:
open "cursor://cli?command=-v"
# Or use AppleScript to trigger internal CLI (if implemented)
osascript -e 'tell app "Cursor" to run CLI command "-v"'
```
However, Cursor likely doesn’t expose such interfaces yet.
---
### ✅ Method 2: **Use an Official CLI Wrapper That Avoids Direct Binary Invocation**
The `cursor` command installed via Homebrew is essentially:
```bash
#!/bin/sh
ELECTRON_RUN_AS_NODE=1 "/Applications/Cursor.app/Contents/MacOS/Cursor" ... "$@"
```
This script **directly invokes the binary**, which triggers provenance enforcement.
#### Alternative: Create a wrapper that communicates via IPC (like VS Code)
But this requires changes in Cursor itself—see Method 3.
---
### ✅ Method 3: **Wait for Official Fix from Cursor Team (Long-Term Solution)**
The only reliable fix is for the **Cursor team to redesign their CLI architecture**:
1. **Split CLI functionality into a separate, signed helper tool** (e.g., `cursor-cli`), instead of reusing the main app binary.
2. Or implement an **XPC service** (e.g., `com.cursor.cli`) that the GUI app hosts, and have the CLI delegate commands through it.
> 💡 Example: **VS Code’s approach**
> The `code` command doesn’t run `ELECTRON_RUN_AS_NODE`. Instead, it sends messages to the already-running VS Code process via a Unix socket or named pipe.
---
### ✅ Method 4: Temporarily Relax Security Policies (Development Machines Only)
> ⚠️ High risk — only recommended on isolated dev machines.
#### Steps:
1. Reboot into **Recovery Mode**
2. Open Terminal and partially disable SIP:
```bash
csrutil enable --without debug
```
> This may loosen AMFI/provenance restrictions for debugging.
3. Reboot and test `cursor -v`
> ❌ **Not guaranteed to work**, and Apple may fully block this in future macOS versions.
---
## 🔍 Technical Explanation: Why Can’t You Remove `provenance`?
- `com.apple.provenance` is a **protected system attribute** managed by the kernel.
- Even `sudo xattr -d com.apple.provenance` will fail with “Operation not permitted”.
- It’s enforced by **Apple Mobile File Integrity (AMFI)**, which ties execution policy to code signature, notarization status, **and how the process was launched**.
- Direct binary invocation = “untrusted context” → AMFI blocks → `SIGKILL`
---
## 📌 Practical Conclusion
| Approach | Feasibility | Notes |
|--------|------------|------|
| Remove `quarantine` | ❌ Already done, ineffective | Issue is now at `provenance` level |
| `spctl --add` | ❌ Disabled in macOS 14.5+ | No longer supported |
| Re-signing | ❌ Useless | App is already notarized |
| **Official CLI redesign** | ✅ Only sustainable fix | Requires action from Cursor team |
| **Avoid CLI for now** | ✅ Temporary workaround | Use GUI instead |
---
## ✅ Recommended Actions
1. **Report this issue to Cursor via Discord**
Link: https://discord.gg/cursor
Channel: `#bug-reports` or `#feature-requests`
**Suggested message**:
> “On macOS Sonoma 14.5+, `cursor -v` is killed with SIGKILL due to `com.apple.provenance`.
> Even though the app is notarized, direct binary invocation is blocked.
> Please consider adopting VS Code’s approach: implement CLI via IPC or a separate signed helper tool.”
2. **Temporary workaround**:
- Use the GUI command palette (`Cmd+Shift+P`) for login and other actions
- Avoid relying on the `cursor` CLI until fixed
---
## 💡 Bonus: Why Doesn’t VS Code Have This Problem?
VS Code’s `code` command works because:
- It **doesn’t use `ELECTRON_RUN_AS_NODE`**
- The main app listens on a **Unix domain socket**
- The `code` script just sends a message to the running instance
- All execution happens in a **trusted, user-approved process context**
Cursor’s CLI, by contrast, **executes JavaScript directly in a new Node-like Electron process**, which macOS treats as high-risk.
---
Unfortunately, **this is not something you can fully resolve with local configuration**. It’s a conflict between Apple’s evolving security model and Cursor’s current architecture. Pushing for an official fix is the only viable path forward.