google-gemini / google-gemini/gemini-cli
bug: file-search result cache reuses prefix matches across different matcher semantics, dropping results
- 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
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