[BUG] Grep tool glob parameter with directory separators silently matches nothing in subdirectories
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The Grep tool's glob parameter silently returns no matches when a glob pattern contains directory separators (/) and the search path is a parent directory.
For example, searching for pull_request_target across multiple repositories:
Grep(
pattern="pull_request_target",
path="/workspaces",
glob=".github/workflows/*.{yml,yaml}"
)
→ "No matches found"
The same search with bash grep -rn on the exact same path finds the expected results. The root cause is that ripgrep's --glob matches patterns containing / against the relative path from the search root. A file at /workspaces/my-repo/.github/workflows/ci.yml has relative path my-repo/.github/workflows/ci.yml, which does not match .github/workflows/*.yml (it doesn't start with .github/).
The correct glob would be **/.github/workflows/*.{yml,yaml}, but the tool definition's description only shows simple filename patterns (*.js, *.{ts,tsx}) and does not mention this behavior.
This is particularly dangerous in security auditing and change impact analysis, where a false negative ("no matches found") is silently accepted as "this pattern does not exist in the codebase."
What Should Happen?
At minimum, the glob parameter description should document that:
- Patterns containing
/match from the start of the path relative to the search directory - Use
**/prefix to match at any depth (e.g.,**/.github/workflows/*.yml)
Ideally, when a glob pattern contains / but not **/, and the search returns 0 results, the tool could emit a hint: "Your glob pattern contains '/' but no '**/' prefix. This only matches paths starting with this pattern relative to the search directory."
Steps to Reproduce
- Have a directory structure like:
````
/parent/
repo-a/.github/workflows/ci.yml
repo-b/.github/workflows/deploy.yml
- Use the Grep tool:
```
Grep(
pattern="some-keyword",
path="/parent",
glob=".github/workflows/*.yml"
)
No matches found` (even if the keyword exists in those files)
Result:
- Fix by adding
**/:
````
Grep(
pattern="some-keyword",
path="/parent",
glob="**/.github/workflows/*.yml"
)
Result: Matches found correctly
- Or use bash grep as workaround:
``bash``
grep -rn "some-keyword" /parent/repo-a/.github/workflows/ /parent/repo-b/.github/workflows/
Result: Matches found correctly
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
2.1.63
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
iTerm2
Additional Information
Related but distinct issues:
- #16936: Grep tool returns 0 matches due to ripgrep ignoring hidden directories (different root cause:
.gitignore/hidden dir exclusion vs glob path resolution) - #5732: Grep tool fails to find existing patterns (general failure, different root cause)
The current glob parameter description in the tool definition is:
"Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\") - maps to rg --glob"
A suggested improvement:
"Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\") - maps to rg --glob. Patterns containing '/' match from the start of the path relative to the search directory. Use '**/' prefix to match at any depth (e.g. \"**/.github/workflows/*.yml\")."
✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗