google-gemini / google-gemini/gemini-cli

bug: glob tool returns 'No files found' for matches under symlinked workspace subdirectories

Open Beginner friendly
#29,040 0 comments 0 reactions 0 assignees View on GitHub
status/need-triage
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.