Bug Description
The childProcessFallback method in packages/core/src/services/shellExecutionService.ts accumulates raw shell output in an uncapped outputChunks: Buffer[] array. While the decoded string state.output is correctly capped at 16MB via appendAndTruncate(), the raw Buffer[] array grows without any limit.
For commands that produce massive output (e.g., cat /dev/urandom, verbose builds, large git log), this will cause a Node.js process out of memory (OOM) crash.
Root Cause
In childProcessFallback() (line ~345), the state is initialized:
const state = {
output: '',
truncated: false,
outputChunks: [] as Buffer[], // ← No size cap
};
Every stdout/stderr chunk is pushed unconditionally at line ~484:
const handleOutput = (data: Buffer, stream: 'stdout' | 'stderr') => {
// ...
state.outputChunks.push(data); // ← Grows forever, no cap!
// ...
};
Meanwhile, the string output IS correctly truncated:
const { newBuffer, truncated } = this.appendAndTruncate(
state.output,
decodedChunk,
MAX_CHILD_PROCESS_BUFFER_SIZE, // 16MB cap
);
But outputChunks is never trimmed — it retains every raw Buffer for the entire lifetime of the command execution. On exit (line ~550), Buffer.concat is called on all accumulated chunks, potentially allocating gigabytes.
Impact
High. A user running any command that produces large output (verbose builds, streaming logs, data processing pipelines) could crash the entire Gemini CLI session with an OOM error.
Reproduction
- Start Gemini CLI
- Ask it to run a command that produces continuous large output (e.g., a verbose build or test run)
- The
outputChunks array grows unbounded in memory
- Node.js crashes with OOM
Environment
- OS: Any
- File:
packages/core/src/services/shellExecutionService.ts, lines 345-544
- Version: Latest main branch
Bug Description
The
childProcessFallbackmethod inpackages/core/src/services/shellExecutionService.tsaccumulates raw shell output in an uncappedoutputChunks: Buffer[]array. While the decoded stringstate.outputis correctly capped at 16MB viaappendAndTruncate(), the rawBuffer[]array grows without any limit.For commands that produce massive output (e.g.,
cat /dev/urandom, verbose builds, largegit log), this will cause a Node.jsprocess out of memory(OOM) crash.Root Cause
In
childProcessFallback()(line ~345), the state is initialized:Every stdout/stderr chunk is pushed unconditionally at line ~484:
Meanwhile, the string output IS correctly truncated:
But
outputChunksis never trimmed — it retains every rawBufferfor the entire lifetime of the command execution. On exit (line ~550),Buffer.concatis called on all accumulated chunks, potentially allocating gigabytes.Impact
High. A user running any command that produces large output (verbose builds, streaming logs, data processing pipelines) could crash the entire Gemini CLI session with an OOM error.
Reproduction
outputChunksarray grows unbounded in memoryEnvironment
packages/core/src/services/shellExecutionService.ts, lines 345-544