`grep_search.includePattern` still silently fails for backslash workspace-root prefixes on Windows
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
@roblourens this is a follow-up to #293428, with two purposes: 1) comprehensive tests verifying that most of #293428 was fixed, but 2) filing a bug for the remaining gap. These tests were done with GPT-5.6 Sol on Max thinking effort.
Since the original bug was mostly fixed, I have changed my standing default instructions from:
> - **`grep_search`** — Use to search file contents. **`includePattern` does _not_ accept the workspace root folder name as a path prefix** (bug #293428) — unlike `file_search`. Use paths relative to the root's content directory (e.g., `src/main/**/Filename.java`), or use `**/Filename.java` to search all roots. To scope to a single root, use a child directory unique to that root (e.g., `nab-service-api/**`), not the root folder name. If `grep_search` returns no results, first verify the `includePattern` does not start with a workspace root folder name. Do not assume the cause is `.gitignore` exclusion.
to:
> - **`grep_search`** — Use to search file contents. In a multi-root workspace, scope `includePattern` to one root with the workspace folder name followed by a forward slash (e.g., `alpha/src/**`), or with the absolute workspace folder path. Always use forward slashes in root-name-prefixed patterns: a backslash at the workspace-name boundary (e.g., `alpha\src/**`) silently returns no matches on Windows. Root-relative patterns search every workspace root.
## Summary
A direct behavioral retest of #293428 confirms that its primary defect is fixed in VS Code 1.131.0: `grep_search.includePattern` now accepts a multi-root workspace folder name as a prefix when the boundary uses `/`, correctly scopes the search to that root, and agrees with `file_search`.
A narrower Windows path-normalization defect remains. The equivalent root-prefixed pattern silently returns no results when the boundary after the workspace folder name uses `\`.
```text
alpha/src/hello.txt ✅
alpha\src\hello.txt ❌
```
This failure is specific to the workspace-name boundary: root-relative backslash patterns and absolute Windows workspace paths both work.
## Relationship to #293428
#293428 reported that workspace-root-name prefixes failed in every slash form. It was closed as completed through microsoft/vscode-copilot-chat#4287 for VS Code 1.112.0 and later marked verified.
The current tests confirm that fix for forward-slash root prefixes and absolute workspace paths. This ticket records those verification results while tracking the remaining separator gap, since #293428 is locked.
No source code was inspected; these results come from direct use of the search tools.
## Environment
- **OS:** Windows 11
- **VS Code:** 1.131.0
- **Commit:** `e4c7e7b1d6d060162f4aa7f8225271b67ce1df75`
- **Architecture:** x64
- **Workspace:** Multi-root (2 roots)
The tested workspace folder names contained spaces and did not occur as internal directory segments, avoiding the false-positive scenario documented in #293428.
## Verification of the Original Fix
| `includePattern` form | `grep_search` |
|---|---:|
| Root-relative: `src/hello.txt` | ✅ |
| Recursive: `**/hello.txt` | ✅ |
| Root-prefixed explicit: `alpha/src/hello.txt` | ✅ |
| Root-prefixed recursive: `alpha/**/hello.txt` | ✅ |
| Absolute workspace path using `/` | ✅ |
| Absolute workspace path using `\` | ✅ |
| Absolute file path | ✅ |
Additional controls confirmed that:
- Root-prefixed patterns matched only the named workspace root.
- A query for content unique to another root correctly returned no results.
- `file_search` and `grep_search` agreed for forward-slash root-prefixed explicit and recursive patterns.
- A nonexistent root or file now returns `(empty)` rather than the former misleading `.gitignore`/`search.exclude` warning.
- `includeIgnoredFiles: true` does not change an invalid-pattern result.
## Remaining Defect
| `includePattern` form | `grep_search` |
|---|---:|
| `alpha/src/hello.txt` | ✅ |
| `alpha/**/hello.txt` | ✅ |
| `alpha\src\hello.txt` | ❌ |
| `alpha\**\hello.txt` | ❌ |
| `alpha\**/hello.txt` | ❌ |
| Root-relative `src\hello.txt` | ✅ |
| Absolute `C:\projects\alpha` | ✅ |
The tool therefore accepts backslashes generally, but not when they follow a workspace folder name used as a scope prefix.
## Steps to Reproduce
### Setup
Create a multi-root workspace:
```text
C:\projects\alpha\
src\
hello.txt contains "hello world"
C:\projects\beta\
src\
hello.txt contains "goodbye world"
```
### Tests
1. Search with:
```text
query: "hello"
includePattern: "alpha/src/hello.txt"
```
The file is found.
2. Repeat with:
```text
query: "hello"
includePattern: "alpha\src\hello.txt"
```
No results are returned.
3. Search root-relatively with:
```text
query: "hello"
includePattern: "src\hello.txt"
```
The file is found, confirming that backslashes are not rejected generally.
4. Search using the absolute Windows workspace path:
```text
query: "hello"
includePattern: "C:\projects\alpha"
```
The file is found and the search is scoped correctly.
## Expected Behavior
On Windows, a root-name-prefixed `includePattern` using `\` should resolve equivalently to the same pattern using `/`.
Alternatively, if backslashes are intentionally unsupported in glob patterns, the tool should reject the input explicitly rather than silently returning an empty result, and separator handling should be consistent across root-relative, root-prefixed, and absolute forms.
## Actual Behavior
A backslash immediately after the workspace folder name prevents root-prefix recognition and silently produces no matches. No diagnostic identifies the path separator as the cause.
## Impact
Windows paths are conventionally represented with backslashes, and models commonly derive an `includePattern` from a path returned by another tool. The silent empty result can therefore be misread as proof that a symbol or file contains no match, leading to incomplete refactors, reviews, dependency updates, or security searches.
The severity is lower than #293428 because reliable multi-root scoping now exists through forward-slash root prefixes and absolute workspace paths. Until this gap is fixed, models should always use forward slashes in root-name-prefixed `grep_search.includePattern` values.
## Recommendation
Normalize `\` to `/` before detecting a workspace-folder-name prefix, or otherwise apply the same separator handling already used for root-relative and absolute Windows paths. Add parity tests covering explicit, recursive, and mixed-separator root-prefixed patterns.
Contributor guide
Assessment
This issue has not been assessed yet.