google-gemini / google-gemini/gemini-cli

bug: read-many-files treats substring overlap as 'explicitly requested' binary asset, inlining unrequested images

Open
#29,045 4 comments 0 reactions 0 assignees View on GitHub
area/core effort/small kind/bug priority/p1 status/manual-triage
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

## What happened?

`read-many-files` decides whether a matched binary asset was "explicitly requested" using **substring containment** between the glob pattern string and the file's stem/extension — not actual pattern matching. Any overlap between a directory-name fragment in the pattern and a binary file's stem marks the asset as requested, so it gets embedded as a base64 `inlineData` part even though the user never asked for binaries. The two checks are also inconsistently cased (extension compare is case-insensitive, stem compare case-sensitive).

## Affected code

`packages/core/src/tools/read-many-files.ts:306-310`:

```ts
const requestedExplicitly = include.some(
(pattern: string) =>
pattern.toLowerCase().includes(fileExtension) ||
pattern.includes(fileNameWithoutExtension),
);
```

## How can this be reproduced?

```json
{ "include": ["**/*report*/**"], "exclude": [] }
```

With a matched file `quarterlyreport.png`: stem `quarterlyreport` is a substring of the pattern → `requestedExplicitly === true` → the PNG is inlined as an image part, consuming large context and surprising the user.

Conversely, a genuine request like `"assets/logo.png"` fails the intent for `logo.PNG` on case-sensitive filesystems due to the asymmetric casing.

## What did you expect to happen?

"Explicitly requested" should mean the include pattern actually matches this specific binary file (e.g., run the pattern through the same matcher used for discovery), not fuzzy string overlap.

## Impact

Unexpected large binary payloads injected into model context; token bloat; potential policy surprises for users who believed they only requested text.

## Suggested direction

Match the file's path against each include pattern with the project's glob engine (`minimatch`/`glob`) instead of `includes()`, normalizing case consistently.

---

*Found by source audit on current `main` (commit `5411f113c`); platform-independent. No open issue/PR covering this was found (searched: read-many-files binary explicitly requested).*

Contributor guide

Open the contributing guide

Research direction

Start in packages/core/src/tools/read-many-files.ts around lines 306-310 and trace the glob matcher used for file discovery. Reproduce the issue with **/*report*/** and quarterlyreport.png, then verify explicit requests such as assets/logo.png and logo.PNG. Done means binary assets are inlined only when the matching include pattern explicitly selects them, with casing handled consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
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.