Repository navigation
Policy Engine rules ignored in non-interactive mode with --approval-mode auto_edit #20469
Description
What happened?
When running gemini-cli in non-interactive mode (using the -p or --prompt flag), the Policy Engine ignores "allow" decisions for specific tools, even when a high-priority rule is explicitly defined. This is because the CLI's configuration layer applies a hardcoded "extra exclude" list to tools like run_shell_command in auto_edit mode when interaction is disabled, which prevents the tool from even being registered, regardless of the Policy Engine's rules.
What did you expect to happen?
The Policy Engine should be the source of truth for tool availability. If a policy explicitly allows a tool (or a specific command prefix), it should be available for execution even in non-interactive mode.
Client information
Client Information
- **CLI Version:** 0.30.0-nightly.20260210.a2174751d - **Git Commit:** ac454bc - **OS:** Linux - **Approval Mode:** auto_edit - **Interface:** Non-interactive (-p flag)Login information
API key
Anything else we need to know?
Steps to Reproduce
- Create a policy file named
repro-policy.toml:[[rule]] toolName = "run_shell_command" commandPrefix = "cargo" decision = "allow" priority = 100
- Create a fake responses file
repro-responses.jsonl:{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I will check cargo options."},{"functionCall":{"args":{"command":"cargo --help"},"name":"run_shell_command"}}]},"finishReason":"STOP"}]}]} - Run the CLI in non-interactive mode with the policy and fake responses:
npm run start -- --model gemini-2.0-flash --fake-responses ./repro-responses.jsonl --policy ./repro-policy.toml --approval-mode auto_edit -p "describe the options to the cargo command" - Observe the error:
Error executing tool run_shell_command: Tool "run_shell_command" not found. Did you mean one of: "get_sheet_content", "read_document", "grep_search"?
Further Research
Behavior Across Approval Modes (Non-interactive)
Testing with a custom allow policy for run_shell_command shows inconsistent behavior across modes:
| Mode | Result | Reasoning |
|---|---|---|
yolo |
Success | Explicitly bypasses hardcoded excludes. |
auto_edit |
Failure | Hardcoded as excluded in packages/cli/src/config/config.ts. |
default |
Failure | Part of defaultExcludes in non-interactive mode. |
plan |
Failure | Part of defaultExcludes in non-interactive mode. |
Root Cause Analysis
It appears that the Config class in packages/core/src/config/config.ts treats hardcoded exclusions and Policy Engine exclusions as a simple union. There is no mechanism for the Policy Engine to "re-allow" a tool that has been statically excluded by the CLI.
When ToolRegistry initializes, it calls config.getExcludeTools(). The implementation is as follows:
// packages/core/src/config/config.ts
getExcludeTools(...): Set<string> | undefined {
// 1. Start with hardcoded excludes from settings/CLI flags
const excludeToolsSet = new Set([...(this.excludeTools ?? [])]);
// 2. Add exclusions from extensions ...
// 3. Add exclusions from the Policy Engine
const policyExclusions = this.policyEngine.getExcludedTools(toolMetadata, allToolNames);
for (const tool of policyExclusions) {
excludeToolsSet.add(tool);
}
return excludeToolsSet;
}Because run_shell_command is added to this.excludeTools by the CLI's configuration logic (in packages/cli/src/config/config.ts), it is present in the set before the Policy Engine is consulted. Even if the Policy Engine has a high-priority allow rule, it simply results in the tool not being added to policyExclusions. It cannot remove the tool from the already-populated excludeToolsSet.
As a result, the tool is never registered in the ToolRegistry, leading to the "Tool not found" error during execution.
Workarounds
I can use --allowed-tools, but that's deprecated. It'd just be nice if this worked before we remove that.
Activity
EricRahm commentedon Feb 26, 2026
I suspect #17170 might be relevant here and perhaps related to #18508
jerop commentedon Feb 26, 2026
Related issues
@EricRahm #17170 is unrelated
fix(cli): defer tool exclusions to policy engine in non-interactive mode
EricRahm commentedon Feb 28, 2026
@jerop just fyi drafted up a PR along with a couple integration tests for policy engine in #20639 No worries if y'all have other plans, hopefully it's helpful either way!
jerop commentedon Mar 2, 2026
Thank you @EricRahm - @kschaab will review and advise
fix(cli): defer tool exclusions to policy engine in non-interactive mode
fix(continuity): register gemini shell tool via settings.json, not ad…