Reliability: Temporary directory leak for background shell executions
Category: Reliability / Resource Leak
Priority: High
Affected Components
packages/core/src/tools/shell.ts
packages/core/src/services/ShellExecutionService.ts
Summary
When a shell command is executed with is_background: true, the CLI creates a temporary directory (gemini-shell-*) to store bgpids.tmp. This directory is never removed after the background task finishes, resulting in a permanent resource leak.
Over time, repeated background executions accumulate orphaned directories inside the system temporary folder.
Current Behavior
The shell tool creates a temporary directory using fs.mkdtempSync() before executing the command.
For foreground commands, the directory is removed in the finally block.
For background commands, cleanup is intentionally skipped:
// Only clean up if NOT running in background.
if (!this.params.is_background) {
// cleanup...
}
However, ownership of this temporary directory is never transferred to ShellExecutionService, so nothing removes it after the background process exits.
Expected Behavior
The temporary directory should be automatically deleted once the background process has completed.
Steps to Reproduce
- Run any background command (e.g.,
sleep 10) with is_background: true.
- Inspect the system temp directory (
/tmp or %TEMP%).
- Observe a new
gemini-shell-* directory.
- Wait for the background process to finish.
- The directory still exists.
Impact
- Temporary directories accumulate indefinitely.
- Long-running CLI sessions or A2A server mode may create thousands of orphaned directories.
- Can eventually consume temporary storage or available inodes, leading to
ENOSPC errors.
Suggested Solution
Transfer ownership of the temporary directory to ShellExecutionService.
A minimal approach would be to:
- Extend
ShellExecutionService.background(...) to accept the tempDir path.
- Store the directory alongside the background process metadata.
- Remove the directory when the background process exits using:
await fsPromises.rm(tempDir, {
recursive: true,
force: true,
});
This keeps the existing behavior unchanged while ensuring temporary resources are cleaned up after the background task completes.
Testing
Add an integration test that:
- Starts a short-lived background command.
- Waits for it to exit.
- Verifies the temporary directory has been deleted.
Acceptance Criteria
Reliability: Temporary directory leak for background shell executions
Category: Reliability / Resource Leak
Priority: High
Affected Components
packages/core/src/tools/shell.tspackages/core/src/services/ShellExecutionService.tsSummary
When a shell command is executed with
is_background: true, the CLI creates a temporary directory (gemini-shell-*) to storebgpids.tmp. This directory is never removed after the background task finishes, resulting in a permanent resource leak.Over time, repeated background executions accumulate orphaned directories inside the system temporary folder.
Current Behavior
The shell tool creates a temporary directory using
fs.mkdtempSync()before executing the command.For foreground commands, the directory is removed in the
finallyblock.For background commands, cleanup is intentionally skipped:
However, ownership of this temporary directory is never transferred to
ShellExecutionService, so nothing removes it after the background process exits.Expected Behavior
The temporary directory should be automatically deleted once the background process has completed.
Steps to Reproduce
sleep 10) withis_background: true./tmpor%TEMP%).gemini-shell-*directory.Impact
ENOSPCerrors.Suggested Solution
Transfer ownership of the temporary directory to
ShellExecutionService.A minimal approach would be to:
ShellExecutionService.background(...)to accept thetempDirpath.This keeps the existing behavior unchanged while ensuring temporary resources are cleaned up after the background task completes.
Testing
Add an integration test that:
Acceptance Criteria
ShellExecutionServiceaccepts ownership of the temporary directory.