google-gemini / google-gemini/gemini-cli

bug: file-search result cache reuses prefix matches across different matcher semantics, dropping results

Open
#29,055 0 comments 0 reactions 0 assignees View on GitHub
area/agent status/need-triage
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

## What happened?

`FileSearch` caches results per query string and optimizes repeated searches by reusing the cached result set of the longest **prefix** query as the candidate pool for the longer query. The optimization assumes "matches(prefix) ⊇ matches(query)" under the *same* matcher — but the code path uses **different matchers depending on the prefix query's shape**: patterns without `*` go through fzf (smart-case: uppercase makes it case-sensitive), while glob-ish patterns use picomatch with `nocase: true`. A case-sensitive fuzzy subset therefore becomes the base pool for a later case-insensitive search, permanently dropping files that only the case-insensitive pass would have matched.

## Affected code

`packages/core/src/utils/filesearch/fileSearch.ts:282-310`:

```ts
} else {
let shouldCache = true;
if (pattern.includes('*') || !this.fzf) {
filteredCandidates = await filter(candidates, pattern, options.signal); // picomatch nocase:true
} else {
const fzfResult = await this.fzf.find(pattern); // fzf smart-case
// ...
if (shouldCache) {
this.resultCache.set(pattern, filteredCandidates);
```

`packages/core/src/utils/filesearch/result-cache.ts:45-54`:

```ts
if (query.startsWith(key) && key.length > bestBaseQuery.length) {
bestBaseQuery = key; // prefix reuse assumes same predicate
}
```

## How can this be reproduced?

1. Search `Src` → served by fzf smart-case; cache stores the case-sensitive subset.
2. Search `SrcUtils` → prefix lookup selects the `Src` subset as base; the subsequent nocase glob pass cannot resurrect files excluded from it.
3. Files like `srcutils/a.ts` (matching case-insensitively but not the earlier case-sensitive fuzzy pass) are missing from results.

## What did you expect to happen?

Result sets should not depend on the order/shapes of previous queries.

## Suggested direction

Only reuse a cached prefix when both queries resolved through the same matcher path (record the matcher kind alongside cached entries), or always seed prefix-reuse from the full candidate list when the matcher differs.

---

*Found by source audit on current `main` (commit `5411f113c`); platform-independent. No open issue/PR covering this was found (searched: file search cache results missing).*

Contributor guide

Open the contributing guide

Research direction

Start with packages/core/src/utils/filesearch/fileSearch.ts:282-310 and packages/core/src/utils/filesearch/result-cache.ts:45-54, then reproduce the issue by searching Src followed by SrcUtils. Trace which matcher path each query uses and how the cached prefix is selected. Done means result sets no longer depend on query order and case-insensitive matches such as srcutils/a.ts are retained.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, search
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.