Retrieval extension spawns runaway rg workers after Yarn node_modules relink

Summary

When running a Yarn install/add that relinks a large node_modules tree inside a React Native/Expo project, Cursor’s retrieval extension can spawn repeated high-CPU rg workers and make the machine unusable until Cursor’s retrieval extension host is killed or Cursor is restarted.

Environment

  • Cursor: 3.3.30
  • macOS: Darwin 25.4.0
  • Package manager: Yarn 4.14.1
  • Yarn linker: nodeLinker: node-modules
  • Project type: React Native / Expo app with large native packages

Reproduction

In a workspace with Yarn Berry using nodeLinker: node-modules, change a large native package so Yarn has to fetch/relink native payloads. For example:

corepack yarn add @shopify/[email protected]

Then flip it back:

corepack yarn add @shopify/[email protected]

Observed behavior

During the Yarn link step, Cursor’s retrieval extension host spawns multiple rg workers like:

rg ** --no-ignore --follow --no-config --no-ignore-global

Observed process tree/source:

Cursor Helper (Plugin): extension-host (retrieval)

The rg workers repeatedly respawned in waves. In one guarded run, the watchdog killed 30 waves of runaway rg workers, usually 7-8 workers per wave, with cumulative rg CPU often around 600-1300%.

Example watchdog lines:

RUNAWAY rgCpu=1366.8 rgCount=8
RUNAWAY rgCpu=1139.6 rgCount=8
RUNAWAY rgCpu=1205.0 rgCount=8

Cursor logs also showed file watcher pressure around the same period:

[File Watcher] Events were dropped by the FSEvents client. File system must be re-scanned.

The machine only became responsive after killing the retrieval extension host / runaway rg workers or restarting Cursor.

What did not fix it

The project already had .cursorignore entries for dependency/build output paths such as:

node_modules/
.yarn/
.expo/
dist/

Adding a dedicated .cursorindexingignore with node_modules, .yarn, build output, and lockfile patterns was not sufficient by itself. With only that indexing ignore in place, the Skia relink still produced repeated runaway rg waves.

Workaround that fixed it in testing

Adding workspace search/watch excludes and disabling search symlink following prevented the runaway in repeated guarded tests after reloading Cursor:

{
  "files.watcherExclude": {
    "**/.expo/**": true,
    "**/.jest-cache/**": true,
    "**/.yarn/**": true,
    "**/build/**": true,
    "**/coverage/**": true,
    "**/dist/**": true,
    "**/node_modules/**": true,
    "**/web-build/**": true
  },
  "search.exclude": {
    "**/.expo": true,
    "**/.jest-cache": true,
    "**/.yarn": true,
    "**/build": true,
    "**/coverage": true,
    "**/dist": true,
    "**/node_modules": true,
    "**/web-build": true
  },
  "search.followSymlinks": false
}

After applying those settings and reloading Cursor, the same Skia version flip completed with:

RUNAWAY_EVENTS=0

Expected behavior

Cursor retrieval/indexing should respect ignore/exclude configuration during dependency relinks, avoid following into large dependency trees, and avoid spawning unbounded high-CPU rg --no-ignore --follow waves after node_modules changes.

Hey @bj97301

You’re right that .cursorignore and .cursorindexingignore might not cover all rg invocations in the retrieval extension.

Your workaround (files.watcherExclude + search.exclude + search.followSymlinks: false) is the right mitigation for now, and I’ve filed this with the team so the retrieval extension respects ignore configuration consistently across all its scan paths.

Thanks for the thorough write-up!

No problem thanks for fixing it and thanks for the awesome product I get to use. Looking forward to using composer 2.5.