google-gemini / google-gemini/gemini-cli

bug: headless mode reports an untrusted folder as trusted to the rest of the app (state/callback mismatch)

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

Description

## What happened?

In `useFolderTrust`, the headless branch sets internal state to the **actual** trust value but reports `onTrustChange(true)` — hardcoded — to the parent, unconditionally. When a headless run starts in an untrusted folder, the app-level `isTrustedFolder` becomes `true` while the hook's own state and warning message say the folder is untrusted. Two sources of truth disagree by construction.

## Affected code

`packages/cli/src/ui/hooks/useFolderTrust.ts:70-82`:

```ts
if (isHeadlessMode()) {
if (isMounted) {
setIsTrusted(trusted); // actual value (may be false)
setIsFolderTrustDialogOpen(false);
onTrustChange(true); // hardcoded true
showUntrustedMessage(); // "this folder is untrusted..."
}
} else if (isMounted) {
setIsTrusted(trusted);
setIsFolderTrustDialogOpen(trusted === undefined);
onTrustChange(trusted); // actual value
showUntrustedMessage();
}
```

## Why this is wrong

The parent wires this to `isTrustedFolder` (`AppContainer.tsx`), which feeds trust-gated behavior (include-directory trust prompting via `useIncludeDirsTrust`, UI state consumed by tool gating). In an untrusted folder under `-p/--prompt` headless mode:

- The user is warned "project settings, hooks, MCPs ... will not be applied", yet
- everything keyed off `isTrustedFolder === true` behaves as if trusted.

One of the two values must be wrong; whichever way the product intent goes (headless = treat as trusted, or propagate real value), the current split guarantees inconsistency.

## How can this be reproduced?

1. Mark a folder DO_NOT_TRUST in trusted folders.
2. Run `gemini -p "list files"` inside it.
3. Observe the untrusted banner while app-level trust state is true.

## What did you expect to happen?

A single consistent trust value propagated for the session.

## Suggested direction

Pass the resolved value through in both branches (headless policy, if any, should be applied before calling the hook), e.g., `onTrustChange(isHeadlessMode() ? true : trusted)` only if that is the documented product decision — otherwise `onTrustChange(trusted)`.

---

*Found by source audit on current `main` (commit `5411f113c`); platform-independent. No open issue/PR covering this was found (searched: headless folder trust).*

Contributor guide

Open the contributing guide

Research direction

Start with packages/cli/src/ui/hooks/useFolderTrust.ts:70-82 and trace the callback through AppContainer.tsx into useIncludeDirsTrust. Reproduce with `gemini -p "list files"` in a DO_NOT_TRUST folder, then confirm the chosen headless policy propagates one consistent value to the hook and parent state.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.