Where does the bug appear (feature/product)?
Cursor CLI
Describe the Bug
When running cursor-agent in non-interactive mode it doesn’t exit at the end.
Steps to Reproduce
On Ubuntu 24.04, login into cursor-agent and have correct permissions.
Run: cursor-agent -p "Hi"
Expected Behavior
Agent should respond, then exit.
Operating System
Linux
Current Cursor Version (Menu → About Cursor → Copy)
cursor-agent version: 2025.09.04-fc40cd1
Does this stop you from using Cursor
Sometimes - I can sometimes use Cursor
deanrie
(Dean Rie)
September 10, 2025, 3:55pm
2
Hey, thanks for the report, we’ll look into it.
Doesn’t work for me either on my MacBook Pro M1 (OS 14.1.2 (23B92))
eeeie
(Eeeie)
September 22, 2025, 2:58pm
4
For me using following script works:
#!/usr/bin/env python3
import argparse
import json
import re
import shutil
import subprocess
import sys
from typing import Any, Optional
def build_prompt(user_prompt: str) -> str:
suffix = " When finished print: ===DONE==="
return f"{user_prompt}{suffix}"
def run_cursor_agent(prompt: str, timeout_seconds: int = 120) -> subprocess.CompletedProcess:
cmd = [
"cursor-agent",
"--print",
"--output-format",
"json",
"--force",
prompt,
]
return subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
timeout=timeout_seconds,
check=False,
)
def parse_json_output(raw: str) -> Optional[Any]:
try:
return json.loads(raw)
except json.JSONDecodeError:
# Fallback: try to extract the largest JSON-looking slice
first = raw.find("{")
last = raw.rfind("}")
if first != -1 and last != -1 and last > first:
slice_ = raw[first : last + 1]
try:
return json.loads(slice_)
except json.JSONDecodeError:
return None
return None
def extract_result_markdown(payload: Any) -> Optional[str]:
if not isinstance(payload, dict):
return None
# User requested: prefer result.result
result_obj = payload.get("result")
if isinstance(result_obj, dict) and isinstance(result_obj.get("result"), str):
return result_obj["result"]
# Fallbacks commonly seen
output_obj = payload.get("output")
if isinstance(output_obj, dict) and isinstance(output_obj.get("result"), str):
return output_obj["result"]
if isinstance(result_obj, str):
return result_obj
return None
def strip_trailing_done_marker(text: str) -> str:
# Remove a trailing ===DONE=== and surrounding whitespace/newlines at the very end
return re.sub(r"\s*===DONE===\s*\Z", "", text, flags=re.MULTILINE)
def print_markdown(md: str) -> None:
# Pretty render with rich if available; otherwise print raw
try:
from rich.console import Console
from rich.markdown import Markdown
Console().print(Markdown(md))
except Exception:
sys.stdout.write(md + ("\n" if not md.endswith("\n") else ""))
def main() -> int:
parser = argparse.ArgumentParser(description="Run cursor-agent and pretty print result.result as Markdown.")
parser.add_argument("prompt", nargs=argparse.REMAINDER, help="Prompt to send to cursor-agent")
parser.add_argument("--timeout", type=int, default=120, help="Timeout in seconds (default: 120)")
args = parser.parse_args()
if not args.prompt:
sys.stderr.write("Usage: cursor-agent-run.py <your prompt>\n")
return 2
user_prompt = " ".join(args.prompt).strip()
real_prompt = build_prompt(user_prompt)
# Ensure cursor-agent exists
if not shutil.which("cursor-agent"):
sys.stderr.write("cursor-agent not found in PATH\n")
return 127
try:
proc = run_cursor_agent(real_prompt, timeout_seconds=args.timeout)
except subprocess.TimeoutExpired:
sys.stderr.write("cursor-agent timed out\n")
return 124
if proc.returncode != 0 and not proc.stdout:
sys.stderr.write(proc.stderr or "cursor-agent failed\n")
return proc.returncode or 1
data = parse_json_output(proc.stdout)
if data is None:
sys.stderr.write("Failed to parse JSON from cursor-agent output\n")
# Show raw output to aid debugging
sys.stdout.write(proc.stdout)
return 1
md = extract_result_markdown(data)
if md is None:
# Fallback: show the entire JSON payload prettified
sys.stdout.write(json.dumps(data, indent=2, ensure_ascii=False) + "\n")
return 0
md = strip_trailing_done_marker(md)
print_markdown(md)
return 0
if __name__ == "__main__":
raise SystemExit(main())
I did more tests and there are folders in which the “-p” exits and some in which it hangs:
HANG in a folder containing a clone of GitHub - lbke/mic2key
HANG in a copy of the folder above
EXIT in the parent folder where I did the clone
HANG in my home folder
HANG in a new folder I create
EXIT in a folder in which I create the script mentioned by @eeeie above.
EXIT in my home folder (why ???)
I don’t see a pattern, and repeat runs are not always consistent.
Where does the bug appear (feature/product)?
Cursor CLI
Describe the Bug
After running the Cursor Agent, once the process finishes, the command does not exit as expected.
Steps to Reproduce
cursor-agent -p --force --output-format text
also i use api key
Expected Behavior
exit command with 0 code
Screenshots / Screen Recordings
Operating System
Linux
Current Cursor Version (Menu → About Cursor → Copy)
cli version: 2025.09.18-7ae6800
For AI issues: which model did you use?
sonnet-4
fuvidani
(Daniel)
September 29, 2025, 3:33pm
7
Hello, we’re facing a similar issue in our GitHub action that’s based on the official Code Review Cookbook . The step `Perform automated code review` does not emit any exit code causing the action to hang in the step indefinitely (even though the agent has long finished the review).
2 Likes
kiritsu0
(Kirill)
September 29, 2025, 5:13pm
9
I’ve run into the same issue — the command doesn’t exit with code 0, but instead the step just hangs and only finishes after 30 minutes. The only workaround so far is setting a timeout. Is there a proper solution to this problem?
1 Like
system
(system)
Closed
October 14, 2025, 2:26pm
11
This topic was automatically closed 22 days after the last reply. New replies are no longer allowed.