google-gemini / google-gemini/gemini-cli
bug: glob tool returns 'No files found' for matches under symlinked workspace subdirectories
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
## What happened?
The glob tool computes relative paths against the **realpath-resolved** target dir and realpath-resolved entries, then re-expands those relative paths against the **raw** `getTargetDir()` and compares them against entries' **raw logical** fullpaths. When the workspace contains a symlinked/junctioned *subdirectory*, the two path spaces differ and the final set-intersection drops every match under that subtree — the tool reports "No files found" despite matches.
Notably, the code computes `realTargetDir` four lines earlier precisely to handle aliasing, then doesn't use it in the comparison step.
## Affected code
`packages/core/src/tools/glob.ts:208-243`:
```ts
let realTargetDir = this.config.getTargetDir();
try { realTargetDir = resolveToRealPath(realTargetDir); } catch { /* raw */ }
const relativePaths = allEntries.map((p) => {
let realFullPath = p.fullpath();
try { realFullPath = resolveToRealPath(realFullPath); } catch { /* raw */ }
return path.relative(realTargetDir, realFullPath); // REAL space
});
// ... filter ...
const filteredAbsolutePaths = new Set(
filteredPaths.map((p) => path.resolve(this.config.getTargetDir(), p)), // RAW space
);
const filteredEntries = allEntries.filter((entry) =>
filteredAbsolutePaths.has(entry.fullpath()), // RAW logical fullpath
);
```
## How can this be reproduced?
1. In the workspace: `mklink /J link C:\elsewhere\data` (or `ln -s`).
2. Call glob with pattern `link/**/*.csv` where matches exist under the real location.
3. All entries under `link/` are filtered out → "No files found".
## What did you expect to happen?
Matches under symlinked subdirectories are returned like any other.
## Suggested direction
Keep both mapping steps in the same space: expand `filteredPaths` against `realTargetDir` and compare against realpath-resolved entry fullpaths (a `Map` avoids recomputing), mirroring how `realTargetDir` is already computed.
---
*Found by source audit on current `main` (commit `5411f113c`); repro needs a symlink/junction subdir (macOS/Windows junctions work unprivileged). No open issue/PR covering this was found (searched: glob symlink no files found).*
Contributor guide
Research direction
Start in packages/core/src/tools/glob.ts around lines 208-243 and trace how real and logical paths are mapped during filtering. Reproduce with a symlink or junction subdirectory and a pattern such as link/**/*.csv. Done means matches under the linked subtree are returned instead of producing "No files found".
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100