Skip to content

fix(core): recognise Windows backslash paths in grep_search output - #13037

Open
guillaume-flambard wants to merge 2 commits into
continuedev:mainfrom
guillaume-flambard:fix/grep-search-windows-backslash-13027
Open

fix(core): recognise Windows backslash paths in grep_search output#13037
guillaume-flambard wants to merge 2 commits into
continuedev:mainfrom
guillaume-flambard:fix/grep-search-windows-backslash-13027

Conversation

@guillaume-flambard

Copy link
Copy Markdown

Problem

Fixes #13027.

grep_search always returns "The search returned no results" on Windows, even when ripgrep finds matches (verified by the reporter with Process Monitor: rg.exe runs and returns results, but the tool reports none).

Root cause

formatGrepSearchResults in core/util/grepSearch.ts detects ripgrep file-heading lines with:

if (line.startsWith("./") || line === "--") {

ripgrep emits headings as the relative path — ./dir/file on POSIX, but .\dir\file on Windows. The startsWith("./") check never matches the Windows form, so no line is counted as a heading, numResults stays 0, and every match is silently discarded. Diagnosed precisely in the issue by @SpikedCola.

Fix

Also accept the .\ prefix:

if (line.startsWith("./") || line.startsWith(".\\") || line === "--") {

POSIX ./ headings and the -- context separator are unchanged.

Tests

Added a unit test in core/util/grepSearch.vitest.ts that feeds backslash-separated ripgrep output and asserts numResults > 0 and the filenames are present — it fails before the change (0 results) and passes after.

I verified the header-detection logic in isolation (the Windows heading goes from unrecognised → recognised, POSIX and -- still recognised). I don't have a Windows machine to run the full agent end-to-end, but the parser is pure and the added test covers the regression in CI.

`formatGrepSearchResults` detected ripgrep file headings with
`line.startsWith("./")`. On Windows ripgrep emits `.\dir\file` instead of
`./dir/file`, so no line was ever recognised as a heading, `numResults` stayed
0, and every match was silently discarded — grep_search always returned "no
results" on Windows even though ripgrep found matches.

Also accept the `.\` prefix. POSIX `./` headings and the `--` context
separator are unchanged. Adds a unit test covering backslash-separated output.

Fixes continuedev#13027
@guillaume-flambard
guillaume-flambard requested a review from a team as a code owner July 27, 2026 11:45
@guillaume-flambard
guillaume-flambard requested review from sestinj and removed request for a team July 27, 2026 11:45
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@SpikedCola

Copy link
Copy Markdown

I have read the CLA Document and I hereby sign the CLA

1 similar comment
@guillaume-flambard

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@guillaume-flambard

Copy link
Copy Markdown
Author

Heads-up on CI: jetbrains-tests is red here, but it's red on every other open PR right now too (#13036, #13034, #13033, #13032, #13031) — a pre-existing failure unrelated to this change. This PR only touches core/util/grepSearch.ts (pure TS parsing); core-checks, which runs the grep unit tests including the new backslash-path case, is green. The build-and-upload-vsix (darwin) cancel and require-all-checks-to-pass failure are both cascades from that jetbrains job.

@LHMQ878

LHMQ878 commented Jul 28, 2026

Copy link
Copy Markdown

Nice find — this is the site the issue names and your diagnosis of it is right.

Heads-up that the same ./ assumption appears in three more places, so this fix on its own leaves the tool broken on Windows in one mode. I've opened #13042 for the remainder rather than touching yours:

  • splitGrepResultsByFile (core/tools/implementations/grepSearch.ts) matches headings with /^\.\/([^\n]+)$/gm. With splitByFile: true, your fix moves Windows from "no results" to returning an empty array of context items — arguably worse, since it reads as a successful call.
  • That function's captured path becomes a type: "file" ContextItem URI, which gets glob-matched for rule application — a backslash escapes in a glob, so src\calc.ts matches nothing.
  • The maxResults truncation in extensions/vscode/src/VsCodeIde.ts splits on (\n--|\n\.\/) and finds no boundaries on Windows.

#13042 pulls the predicate into a shared isGrepResultPathLine() + GREP_RESULT_PATH_PREFIX_SOURCE in core/util/grepSearch.ts so the sites can't drift apart again, which means it overlaps your one-line change. Your PR is first — if maintainers merge it, I'll rebase mine and drop that hunk. Entirely happy the other way round too, or to fold everything into yours if you'd prefer to carry it. Just flagging so neither of us gets closed as a duplicate.

@guillaume-flambard

Copy link
Copy Markdown
Author

Thanks @LHMQ878, this is a great catch and your breakdown is exactly right. I only fixed the detection in formatGrepSearchResults, and you are correct that with splitByFile: true that leaves the tool returning an empty result set on Windows, which reads as success and is arguably worse than the original "no results". The glob backslash-escaping and the VsCodeIde.ts maxResults split are both real too.

Pulling the predicate into a shared isGrepResultPathLine() + GREP_RESULT_PATH_PREFIX_SOURCE in core/util/grepSearch.ts is the right call so these four sites can't drift apart again. I am happy to keep this PR minimal and let it merge first, then you rebase #13042 and fold my one-liner into the shared helper. If the maintainers would rather have it all in one place, I am also fine closing this in favour of #13042 and having the fix land there. Whatever keeps it clean and avoids a duplicate on your side.

Either way, thanks for opening #13042 and flagging it here rather than quietly overlapping. Ping me if a review on it would help.

@LHMQ878

LHMQ878 commented Jul 28, 2026

Copy link
Copy Markdown

Thanks for the generous reply, and for offering either way — my vote is your first option: land #13037 as-is, I rebase #13042 on top. Reasons, in order of how much they matter:

  1. You found it first. fix(core): recognise Windows backslash paths in grep_search output #13037 predates fix(core): handle Windows separators in the remaining grep_search parsers #13042 by ~18h and correctly identifies the site the issue names. That should be in the history as yours.
  2. Your PR is the low-risk half. One predicate widened, with a test. It can go in on its own review budget. fix(core): handle Windows separators in the remaining grep_search parsers #13042 touches a context-item URI shape and a VS Code truncation path — that deserves separate scrutiny and shouldn't hold up the fix for the reported symptom.
  3. The rebase is cheap on my side. Your line becomes isGrepResultPathLine(line); the helper and GREP_RESULT_PATH_PREFIX_SOURCE land in fix(core): handle Windows separators in the remaining grep_search parsers #13042 with the other three sites. One-line conflict, and I'll keep your comment text — it explains the #13027 link better than mine did.

One thing worth flagging to whoever triages this: there is now a third PR on the same line. #13043 (opened this morning) changes core/util/grepSearch.ts:60 to exactly

-    if (line.startsWith("./") || line === "--") {
+    if (line.startsWith("./") || line.startsWith(".\\") || line === "--") {

which is character-identical to yours minus the comment. So #13037 and #13043 are true duplicates of each other, and #13042 is the superset. Cleanest outcome is probably: merge #13037, close #13043 as a duplicate of it, then review #13042 for the remaining three sites. I have no stake in which of #13037/#13043 wins — I'm flagging it only so a maintainer doesn't merge one and then get a confusing conflict from the other.

On CI, for anyone reading this thread: your read is right and it has not changed. jetbrains-tests fails on Autocomplete.kt:42 on every open PR I sampled, including the maintainers' own automated dependency bumps (#13034, #13033, #13032, all by @sestinj). It's a JetBrains UI starter test that needs a live completion; nothing in any of these three PRs can reach it. require-all-checks-to-pass is just its aggregator.

And yes — a review on #13042 would genuinely help, especially the filepath.replace(/\\/g, "/") in splitGrepResultsByFile. That normalisation is the one judgement call in the PR rather than a mechanical widening: those strings become file context-item URIs which get glob-matched for rule application, and in a glob a backslash is an escape character, not a separator. I believe normalising is correct there, but it is the part I'd most want a second opinion on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

grep_search tool returns no results on Windows due to backslash path separator in ripgrep output

3 participants