Agent Shell stays running after the process is done; later git/xcodebuild commands hang with empty output (macOS, zsh, git worktrees)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Agent Shell / Cursor terminal sessions get stuck in running after the OS process has already finished (or never printed a byte). After that, every later Agent Shell call queues or hangs: git, python, xcodebuild, even a trivial timer/sleep “watch the log” command.

This is not one flaky git repo. The same session-desync happens for:

Xcode: xcodebuild build|test redirected to a log (> tmp/foo.log 2>&1, often started with block_until_ms: 0 / background &). The log already contains TEST SUCCEEDED / TEST FAILED / BUILD SUCCEEDED. The terminal UI still shows running for many minutes. A later inspection can find the pid in the session header already dead, no children.
Python: python -u script.py 2>&1 | tee tmp/foo.log (installers, device scripts, anything that runs >30s). Same zombie running. A second Python one-liner never starts.
Git: git status, git pull, git checkout, git worktree list. In Terminal.app they return instantly. In Agent Shell they sit at running with empty output until the human Aborts.
Basic monitoring: we tried not blocking the PTY: start the job, then later Read/Grep the log, or a short sleep / “wait until the log matches SUCCEEDED”. That monitoring Shell also hangs or never fires. AwaitShell / output-pattern wait is unusable for us — it either never completes or stacks behind the zombie. ps/pgrep as a health check is worse: it queues behind the stuck session and freezes the agent.
We already encoded “one long command at a time; don’t poll; read the log file” as always-on project rules because stacking a second Shell is what makes the product look dead. Those rules do not prevent the first session from lying about running. Abort/Stop in the UI often does not match process lifetime (UI running + pid gone, or Abort with zero stdout so we cannot tell if the command started).

macOS, zsh, Agent mode. Multiple git worktrees. Repro is easiest after any long job or a large checkout, but even git rev-parse --abbrev-ref HEAD has hung with empty output.

Steps to Reproduce

We do not have a 3-line public fixture, but this is consistent on our machine:

Open a medium/large repo in Agent mode (ours is an Xcode iOS app; git worktrees optional but make git hangs more obvious).
From the agent, run a long command with output redirected to a file, and do not keep the PTY in the foreground, e.g.
xcodebuild … test > tmp/run.log 2>&1
or
python -u long_script.py > tmp/run.log 2>&1
with Agent Shell block_until_ms: 0 (or equivalent background).
Wait until tmp/run.log clearly shows a terminal result (TEST FAILED, Python traceback, PASS: installed, etc.).
Observe the Cursor terminal session: it often still says running.
Without Stop-ing that session, ask the agent to run any of:
git rev-parse --abbrev-ref HEAD
python -c ‘print(“ok”)’
sleep 2; echo still-alive
“poll until the log contains SUCCEEDED” / AwaitShell on that log
Result: new Shell hangs, empty output, or never starts. The UI looks frozen.
Stop/Abort the old session. Ask the agent to run the same short command again. It can still hang (empty running until Abort).
Paste the identical short command into Terminal.app → returns immediately.
Optional git-worktree variant: git pull --ff-only in worktree A (large tree). Fast-forward prints in the log, then a chained git status -sb never returns in Agent Shell. git worktree list from the agent hangs; Terminal.app is instant.

Expected Behavior

When the user command’s process (and its process group) has exited, the Agent terminal session must go idle, not stay running.
Redirecting to a file (> log 2>&1) or starting with block_until_ms: 0 must be either fully supported (session completes when the process exits) or rejected immediately — not a zombie session that poisons the next tool call.
After a session is Stopped/Aborted, the next Shell tool call must get a fresh process group and run. Trivial git / python -c / sleep 2 must return in Agent Shell about as fast as in Terminal.app.
Log-file monitoring (Read/Grep the log, or wait-until-regex) must work without attaching to the original PTY. A timer/sleep used only to wait should not hang forever with empty output.
If a command exceeds block_until_ms, the agent should get a clear “moved to background, pid=…” result, and later completion should be observable without opening a second Shell that queues forever.

Operating System

MacOS

Version Information

Cursor Agent (Agent mode, project rules always-on)
macOS darwin 25.6.0, default shell zsh
Large native repo: Xcode iOS app, multiple git worktrees sharing one .git
Typical long job: xcodebuild test (10+ minutes)
Typical short job: git status / git checkout / git worktree list

For AI issues: which model did you use?

grok 4.6

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey @FiveTimes thanks, great write-up. What you’re describing isn’t intended behavior and it’s not something in your setup. This is an issue we’re already tracking, and your report helps.

Two things that should unblock you right now:

  • When a session wedges, recover with Developer: Reload Window (Cmd+Shift+P), not Stop + retry - Stop tends to leave the wedged shell in place, so the next command still hangs.
  • For long jobs, redirect to a file (> tmp/run.log 2>&1) instead of | tee, then Read/Grep the log rather than watching the terminal.

One thing that’d help us pin it down when it next happens: open View → Output → Extension Host and paste the last few minutes (an empty panel, or “unresponsive”/restart lines, are exactly what we’re after). I’ll follow up here as we learn more.

Cursor Agent Shell stays UI-running after the OS process exits.
Extension Host (2026-09-08) shows Python Envs hitting a proposed API Cursor does not grant to 3rd-party extensions, then the extension host restarts.

ms-python.vscode-python-envs 1.36.0
Error: Extension ‘ms-python.vscode-python-envs’ CANNOT use API proposal: terminalDataWriteEvent.
Its package.json#enabledApiProposals-property declares: terminalShellEnv but NOT terminalDataWriteEvent.
(Note in the same error: cursor / cursorAgentHost / cursorNoDeps / control / cursorPseudoterminal are only available for built-in extensions.)

Stack: autoActivateOnTerminalOpen → waitForShellIntegration → onDidWriteTerminalData

Timeline:
20:11:10 first Agent Shell / xcodebuild — same terminalDataWriteEvent error
20:32:24 Extension host terminating: renderer closed the MessagePort (×3), pids exit 0
20:35:54 Extension host started (restart)
20:43:26 second Agent Shell — same error again

No literal “unresponsive” token; terminating + new host started is the restart.
macOS darwin, sandbox helper present, default shell zsh.

@FiveTimes the Python Environments extension (ms-python.vscode-python-envs) is hooking terminal output through an API Cursor doesn’t grant to third-party extensions, and that’s what’s restarting the extension host and orphaning your shell sessions, so they stay “running.”

Try disabling that extension (Extensions panel, search “Python Environments” by ms-python, Disable, then Developer: Reload Window), then run your usual long-job plus a follow-up command. The stuck-shell behavior should stop. If you rely on it, turning off its terminal auto-activation is worth a try, but disabling is the cleanest test. Let me know how it goes, and I’ll add your logs to what we’re tracking.

I uninstalled all Python extensions in my IDE, but it didn’t help. Your team’s work is very frustrating; cursor is a terrible product for me and a waste of my $60!

If I need to reload every time it gets stuck, why should I use Cursor?

See more info. below:
Agent Shell still wedges after redirected long jobs — ExtHost is silent for the whole failure window

Following Cursor’s guidance (Reload Window not Stop; redirect long jobs to a file and Read the log, no | tee). Workarounds help recover; they don’t fix it.

Repro (today)
macOS, Auto models, Agent Shell, long xcodebuild test redirected to a log file.
Log already had a finished result (** TEST FAILED ** + Apple’s ~600s simulator diagnostics timeout).
Agent Shell stayed status: running 15+ min after that, empty body (metadata only).
Later shells never started: rg on the same log, even kill , then a trivial ls — all hung until Developer: Reload Window.
Extension Host (View → Output → Extension Host) — useful part

  1. Empty during the wedge (exact window ~18:02–18:21 local)
    No ExtHost lines at all for that interval: no shell-exec lifecycle, no error, no “unresponsive”. Last activity before the wedge was an ExtHost restart at 17:42:09; after activation finished (~17:42:14) the paste ends with silence through the entire wedge.

  2. Multiple ExtHost restarts same day (same workspace)

Local time Event
15:06:39
ExtHost started (multi-host pids)
16:24:17
ExtHost started again (~1h18m later)
17:42:09
ExtHost started again (~1h18m later); last lines before wedge
Long silent gaps between restarts; nothing logged while Agent Shell was stuck.

  1. Recurring on every ExtHost start
    Many of:

[error] No bundle location found for extension anysphere.cursor-agent-exec
[error] No bundle location found for extension anysphere.cursor-agent-host
[error] No bundle location found for extension anysphere.cursor-retrieval
… (other anysphere.cursor-* / cursor.*)
Extensions still report Extension activated success afterward.

  1. Shell-exec only at host startup
    [ExtHostShellExec] / sandbox probe only at ExtHost start (Sandbox support detected: true, darwin). No per-command shell-exec trace for the wedged job or the hung follow-ups (kill included).

Ask
Is ExtHost expected to stay blank while the Agent Shell runner is wedged? Any flag/build that adds per-command shell-exec lifecycle logs so the next wedge is diagnosable without guessing?

@FiveTimes, sorry about this, and thanks for testing that. Uninstalling the Python extensions changed nothing, so that wasn’t the cause. Your logs point to the Extension Host restarting mid-job and orphaning the shell, which is the behavior we’re tracking. Reload Window stays the fastest recovery for now.

Two quick answers: the blank Extension Host panel during the wedge is expected (no per-command shell logging there today), and the No bundle location ... anysphere.cursor-* lines are harmless noise. If it happens again, the Main and Window channels (View > Output) around one of those restarts would show why the host went down, which is the piece we still need. I’ll post here when there’s movement.

I have uninstall Cursor IDE and canceled my subscription. I will use the CLI to consume my remaining usage, even it’s has same issue some time. If your team finaly close this issue, I will consider returning.

Before you go, one setting we hadn’t tried that targets this directly: Cursor Settings > Agents > Legacy Terminal Tool. It runs agent terminal commands through a simpler path that avoids what was wedging your sessions, so if you reinstall to use up the remaining time it’s worth switching on before a long xcodebuild run. It won’t stop the extension host from restarting, but your shells shouldn’t get orphaned the same way when it does.

The core issue is still tracked on our side. No timeline I can share, but I’ll post here when it moves, and I’m sorry it got to this point.