[Bug] VS Code extension: ripgrep glob anchored at `/` due to off-by-one in path relativization

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 1, 2026

Bug Description

# VS Code extension: ripgrep glob anchored at / due to off-by-one when relativizing absolute paths ## Summary The VS Code extension resolves file references from the conversation by spawning rg --files -g <path>. When the referenced path is absolute, the glob it passes is the absolute path with the workspace root prefix stripped but the path separator left in place, producing a glob anchored at the filesystem root. Combined with --no-ignore --follow, this triggers a full-disk traversal that follows symlinks and never terminates in practice. This appears to be the underlying cause of #8973 and #24778 (and their duplicates). Previous reports assumed the malformed path came from a file in the user's project. It does not — it is produced by the extension's own path handling, which is why it reproduces so easily and so often. ## Environment - OS: Linux (GNOME) — <distro / kernel> - VS Code: <version> (system install at /usr/share/code) - Extension: anthropic.claude-code <version> (linux-x64) - ripgrep: bundled @vscode/ripgrep-universal/bin/linux-x64/rg ## Observed behaviour Multiple long-lived rg processes pegging CPU. Captured command line: `` /usr/share/code/resources/app/node_modules.asar.unpacked/@vscode/ripgrep-universal/bin/linux-x64/rg \ --files --hidden --case-sensitive --no-require-git \ -g /doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md \ -g '!**/.git' -g '!**/.svn' -g '!**/.hg' -g '!**/.DS_Store' -g '!**/Thumbs.db' \ -g '!/{**/node_modules,**/bower_components,...}' \ --no-ignore --follow --no-config --no-ignore-global ` Note that the exclusion globs are **also** anchored at / (-g '!/{**/node_modules,...}'), so they do not apply during the root-level traversal and provide no protection. ## Root cause The workspace root is /home/<user>/src/spectrum/jnext. Searching the session transcripts under ~/.claude/projects/<workspace-slug>/*.jsonl for every occurrence of the filename shows that **no relative path with a leading slash exists anywhere**. Every occurrence is either properly relative or fully absolute: ` doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md [doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md](doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md) /home/<user>/src/spectrum/jnext/doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md ` Lining up the absolute form against the emitted glob: ` /home/<user>/src/spectrum/jnext/doc/design/TRACEABILITY-MATRIX-GENERATION-PLAN.md |________ workspace root ______||_____________ emitted as -g ___________________| ` The prefix is being stripped by string length rather than by path semantics — effectively abs.slice(root.length) instead of abs.slice(root.length + 1) or path.relative(root, abs). The leftover separator is the leading / that makes ripgrep search from the filesystem root. **This means any absolute path appearing in a conversation is sufficient to trigger the bug.** No malformed input from the user is required. ## Secondary issue: prefix-based containment check The same class of bug appears in the workspace containment check. With: ` /home/<user>/src/spectrum/jnext <- workspace root /home/<user>/src/spectrum/jnext-worktrees/ <- sibling directory ` the workspace root is a literal string prefix of the sibling path. A startsWith() check will treat paths under jnext-worktrees/ as inside the workspace and strip the prefix, yielding garbage such as -worktrees/agent-dedup1/doc/.... Containment should be tested per path segment, not by string prefix. ## Impact - Multiple cores pinned indefinitely; machine becomes unusable - --follow with --no-ignore traverses /proc, /sys and network mounts, and can loop on symlink cycles - Processes survive VS Code restarts by respawning, and reappear when a prior session is reopened with /resume, because the triggering reference lives in the session transcript rather than in any project file ## Expected behaviour 1. Use path.relative(workspaceRoot, absolutePath) so the glob is genuinely relative to the workspace. 2. Test workspace containment by path segment, not string prefix. 3. Scope the search to the workspace directory rather than relying on the glob alone; pass the search root explicitly to rg. 4. Drop --follow, or bound the search with a timeout, so a malformed glob degrades into a slow search rather than an unbounded one. ## Workaround - "search.followSymlinks": false in workspace settings - A timer that kills rg processes exceeding a short runtime threshold - Avoid opening $HOME or high-level directories as the workspace ## Reproduction 1. Open a project workspace in VS Code with the extension active. 2. Have the assistant reference a project file by absolute path in its response. 3. Observe rg spawned with a glob beginning with /, and CPU saturation. readlink /proc/<…
Note: Content was truncated.

View original on GitHub ↗