Shell tool hangs indefinitely when running rg (ripgrep) recursive directory search

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Running rg <pattern> (ripgrep recursive directory search) through the Shell tool never completes. The tool reports the command was “sent to background” after the 30-second timeout, but the terminal output file shows zero output and the command appears to hang indefinitely. The rg process itself exits correctly in under 1 second — this is a process-exit detection bug in the Shell tool infrastructure, not an AI model issue.

Steps to Reproduce

  1. Open any git repo with source files
  2. In Agent mode, have the agent run a bare ripgrep command: rg -i somepattern
  3. Observe: the Shell tool times out after 30s and backgrounds the command
  4. Check the terminal output file — it shows zero output and no exit code, even though rg finished instantly

Expected Behavior

Command completes in under 1 second (as it does in a real terminal or when wrapped in sh -c).

Operating System

Linux

Version Information

Version: 2.6.19 (system setup)
VSCode Version: 1.105.1
Commit: 224838f96445be37e3db643a163a817c15b36060
Date: 2026-03-12T04:07:27.435Z
Build Type: Stable
Release Track: Default
Electron: 39.4.0
Chromium: 142.0.7444.265
Node.js: 22.22.0
V8: 14.2.231.22-electron.0
OS: Windows_NT x64 10.0.26200

For AI issues: which model did you use?

Claude Opus 4.5 — but this is not model-dependent. It’s a Shell tool infrastructure bug. The model correctly issues the rg command; the Shell tool fails to detect when rg exits.

Additional Information

Detailed diagnosis:

Command Result
rg --version Works
rg -i pattern single_file.cpp Works
rg -i pattern (recursive) Hangs forever
sh -c 'rg -i pattern' Works
bash -c 'rg -i pattern' Works
timeout 5 rg -i pattern Works
strace -f rg -i pattern Works
rg -i pattern & wait $! Works
grep -ri pattern Works

Key findings:

  • Shell tool’s persistent shell is non-interactive zsh with stdin/stdout as sockets (not pty)
  • strace confirms rg calls exit_group(1) cleanly; all worker threads exit normally
  • The bug only manifests when rg is the direct foreground process and produces no stdout output
  • Any wrapper (sh -c, timeout, strace, background+wait) causes normal completion

Hypothesis: The Shell tool’s process-exit detection doesn’t fire when a multithreaded Rust binary using exit_group() is the direct foreground child with no stdout output over a socket.

Workaround: Use the built-in Grep tool (which works perfectly), or wrap rg in sh -c '...'.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Thanks for the thorough bug report! I was able to reproduce this on macOS as well, so it’s not platform-specific.

In the meantime, besides the workarounds you already mentioned, passing an explicit path works reliably as a workaround: rg -i pattern . instead of rg -i pattern.

This has been filed internally and we’ll follow up here with any updates.

1 Like

Thank Cursor for the detailed analysis and bug report itself! I’m not sure I changed a single character

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