start_search maxResults is per-file and unbounded collector can exhaust memory
Summary
start_search can accumulate an unbounded amount of JSON search output in memory. On a sufficiently large project, this can create severe system memory pressure and make the host unresponsive.
This report concerns the Desktop Commander search implementation, not a generic Claude Desktop memory-leak claim.
Environment
- Desktop Commander extension: 0.2.46
- Host: macOS on Apple Silicon, 64 GB RAM
- Client: Claude Desktop
Observed behavior
A content search over one large project caused the parent process tree footprint to rise from roughly 5 GB to over 70 GB in about two minutes. The bundled ripgrep descendant was the largest individual RSS consumer, reaching roughly 14 GB. The system became severely memory pressured and unresponsive.
The search used the equivalent of:
start_search(path: /path/to/large-project, query: <generic pattern>, searchType: content, maxResults: 200)No reliable synthetic reproduction fixture is available yet. Sanitized diagnostics and code references can be supplied on request.
Likely cause
In dist/search-manager.js in v0.2.46:
maxResultsis passed to ripgrep as-m. Ripgrep defines-mas a per-file match cap, not a global result cap. A large number of files can therefore produce far more than the requested number of results.- The content-search command uses JSON output with context. The handler parses every JSON line and appends every match/context object to
session.results, with no global count or byte budget. - Content searches have no default timeout unless the caller supplies one.
- Completed result arrays remain resident until later cleanup.
This makes maxResults misleading as a memory bound. --max-columns is not a mitigation here because ripgrep JSON mode ignores it.
Expected behavior
- Enforce a true global result and/or byte cap in the collector.
- Stop the child process immediately when that cap is reached.
- Apply a conservative default timeout or output budget to content searches.
- Stream or paginate results instead of retaining an unbounded in-memory session array.
- Tie cancellation and cleanup tightly to the search lifecycle.
- Document that ripgrep
-mis per-file, or avoid exposing it as globalmaxResults.
Impact
A routine-looking content search on a large workspace can exhaust tens of gigabytes of memory, stall the host, and disrupt unrelated work.
Source: wonderwhy-er/DesktopCommanderMCP