google-gemini / google-gemini/gemini-cli
Gemini CLI executes a tool side effect after SIGINT cancellation
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
## What happened?
Gemini CLI can continue consuming delayed provider tool calls after a user interrupt has already been delivered, execute the local shell side effect, and then submit repeated tool results.
The standalone reproducer installs public `@google/gemini-cli@0.47.0`, starts a local mock provider, schedules `SIGINT` 500 ms after the CLI starts, delays the provider tool call for 1200 ms, and verifies that the delayed tool call still writes a marker file after cancellation.
## What did you expect to happen?
After user cancellation, Gemini CLI should stop consuming later provider-stream tool calls and should not execute their local side effects.
## Client information
```console
Package: @google/gemini-cli
Affected version checked locally: 0.47.0
Current npm latest checked on 2026-06-22: 0.47.0
Upstream repository: https://github.com/google-gemini/gemini-cli
Platform: Linux x86_64 in Docker (node:24-bookworm)
Interface: CLI
```
## Login information
API key flow against a local Gemini-compatible mock endpoint. The reproduction uses a fake API key and makes no live Gemini request.
## Anything else we need to know?
**Standalone reproduction**
Prerequisites: Docker, Python 3, and the GitHub CLI (`gh`) for the clone command below. The linked reproducer is self-contained and uses only Python standard-library modules plus Docker. It builds the affected CLI version from the public npm package and starts a local mock provider; it does not require this repository or any private fuzzing harness. The Docker run is limited to 2 CPUs and 4 GiB RAM by default.
Complete self-contained reproducer: https://gist.github.com/N0zoM1z0/446a235b2589d133fdd38ab5832f5bb6
The Gist contains `gemini-cli-late-effect-after-cancel.reproduce.py`. Download and run:
```bash
gh gist clone 446a235b2589d133fdd38ab5832f5bb6 gemini-cli-late-effect-after-cancel-reproducer
cd gemini-cli-late-effect-after-cancel-reproducer
python3 gemini-cli-late-effect-after-cancel.reproduce.py
```
To reuse an already-built local image:
```bash
python3 gemini-cli-late-effect-after-cancel.reproduce.py --skip-build
```
Key output from a local run against the affected version:
```text
provider_requests_at_least: observed=6 expected>=1
tool_result_after_signal: observed=14 expected>=1
side_effect_file_contains gemini-cli-late-effect-after-cancel.log 'late-effect-after-signal': observed=True
REPRODUCED
```
**Steps to reproduce**
Run the standalone reproducer above.
**Actual behavior**
Gemini CLI receives `SIGINT` before the delayed provider tool call is emitted, but it still executes the later shell tool side effect and submits tool results for `late_after_cancel`.
**Expected behavior**
Gemini CLI should cancel the in-flight stream and ignore later tool calls once user cancellation has been requested.
**Public-upstream status**
This report targets stock public `@google/gemini-cli@0.47.0`, which is the current npm latest checked on 2026-06-22. This is separate from the already filed duplicate tool-result issue because it validates cancellation semantics.
Contributor guide
Research direction
Start by running gemini-cli-late-effect-after-cancel.reproduce.py from the linked Gist to observe SIGINT handling, delayed tool calls, and repeated results. Trace the CLI's cancellation and tool-execution entry points; done means later provider tool calls produce neither local side effects nor submitted tool results after cancellation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100