bug: shell execution runs exit handling twice on spawn failure ('error' and 'close' both call handleExit)

Open Beginner friendly
#29,057 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
node.js, typescript
Domain
cli

Research direction

Start in packages/core/src/services/shellExecutionService.ts:819-838 and inspect how the child 'error' and 'close' handlers call handleExit. Reproduce the issue with a command whose spawn fails, then verify that one process run emits one exit event and performs cleanup and background-history finalization once.

Written by the indexing model from the issue text.

Description

area/agent status/need-triage

What happened?

In the shell execution pipeline, both the child 'error' and 'close' events invoke handleExit(), and handleExit has no re-entrancy guard. Per Node's documented behavior, 'close' fires after 'error' when spawning fails — so every failed spawn runs exit handling twice: onOutputEvent({ type: 'exit', ... }) fires twice, background-history finalization runs twice, and cmdCleanup?.() executes twice. If 'error' fires mid-run on a successfully spawned child (e.g., kill/IPC failure), the result settles early on partial output before 'close' arrives.

Affected code

packages/core/src/services/shellExecutionService.ts:819-838:

child.on('error', (err) => {
  error = err;
  handleExit(1, null);        // first settlement
});
// ...
child.on('close', (code, signal) => {
  handleExit(code, signal);   // second settlement for the same run
});

How can this be reproduced?

Execute a command whose spawn fails (nonexistent executable / bad sandbox path). Observe two exit output events emitted for the single run (and doubled cleanup calls).

What did you expect to happen?

Exactly one exit settlement per process run.

Suggested direction

Add a settled flag inside handleExit (return immediately on second call), matching the pattern used elsewhere in this file for stream finalization.


Found by source audit on current main (commit 5411f113c); platform-independent. No open issue/PR covering this was found (searched: shell exit event twice).

Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 4h
Merged PRs (30d)
43

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from google-gemini/gemini-cli

All issues in google-gemini/gemini-cli

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.