Skip to content

[Bugfix #680] Prevent V8 heap exhaustion in gemini consult#681

Merged
waleedkadous merged 1 commit intomainfrom
builder/bugfix-680-consult-gemini-crashes-on-larg
Apr 18, 2026
Merged

[Bugfix #680] Prevent V8 heap exhaustion in gemini consult#681
waleedkadous merged 1 commit intomainfrom
builder/bugfix-680-consult-gemini-crashes-on-larg

Conversation

@waleedkadous
Copy link
Copy Markdown
Contributor

@waleedkadous waleedkadous commented Apr 18, 2026

Summary

Fixes #680

consult -m gemini was crashing on PR diffs >500KB due to V8 old-space
exhaustion in the spawned gemini-cli subprocess. Truncated stdout caused
JSON.parse to fail, and CMAP silently degraded to 2-way exactly when 3-way
signal mattered most (shannon PRs #642, #650, #568, #629).

Root Cause

gemini-cli v0.37.x runs out of its default V8 old-space (~1.7 GB) during
non-interactive mode:

  • loadServerHierarchicalMemory / JIT context walk (graceful-fs wrapping
    fs.readdir) produces the ArrayUnshift + AfterScanDir frames
  • Large prompt passed via argv, which V8 buffers in both argv and prompt paths
  • advanced.autoConfigureMemory exists upstream but defaults OFF

Only gemini was affected because only gemini is shelled out and only gemini
parses JSON from a buffered child stdout. Codex and Claude run in-process.

Fix

packages/codev/src/commands/consult/index.ts — two complementary mitigations:

  1. Bump heap via NODE_OPTIONS (--max-old-space-size=8192). Survives
    gemini-cli's internal relaunch. Preserves any caller-supplied NODE_OPTIONS.
  2. Pipe the prompt via stdin instead of argv. Avoids ARG_MAX and keeps V8
    from holding the prompt buffer twice. EPIPE from an early child exit is
    handled gracefully so we surface the underlying error, not the pipe close.

No changes to codex or claude paths (unaffected).

Test Plan

  • Added 4 regression tests (Gemini large-prompt crash mitigation (Bugfix #680))
    • NODE_OPTIONS contains --max-old-space-size=8192
    • Query is NOT passed as positional argv
    • stdio[0] is 'pipe' (not 'ignore')
    • Caller's existing NODE_OPTIONS is preserved and appended to
  • Full unit suite: 41 passed (previously 37) + 2 pre-existing failures
    unrelated to this change (skeleton fallback — fail on main as well)
  • End-to-end manual test: consult -m gemini --prompt "What is 1+1?"
    returns 2 in ~4s with the new stdin path

Diff Size

 2 files changed, 168 insertions(+), 4 deletions(-)

Net diff: 172 LOC (under 300).

CMAP Review

All three verdicts: APPROVE / CONFIDENCE: HIGH / KEY_ISSUES: None

Model Verdict Summary
Gemini APPROVE Correctly resolves V8 heap exhaustion crashes for large PR diffs by buffering prompt over stdin and safely boosting NODE_OPTIONS heap allocations.
Codex APPROVE The Gemini consult mitigation is correctly scoped and should prevent large prompts from being passed through argv while increasing the spawned CLI heap.
Claude APPROVE Clean, well-tested two-pronged fix for V8 heap exhaustion in gemini consult — bump heap + pipe stdin — with 4 targeted regression tests and no impact to other models.

Full review transcripts: /tmp/bugfix-680-cmap-{gemini,codex,claude}.md

…rge PRs

gemini-cli v0.37.x crashes on PR diffs >500KB due to V8 old-space
exhaustion in the spawned subprocess. Two complementary mitigations:

1. Set NODE_OPTIONS=--max-old-space-size=8192 on the spawned env. This
   survives gemini-cli's internal relaunch and gives it enough heap to
   finish directory walks and buffer large responses.

2. Pipe the prompt via stdin instead of argv. Avoids ARG_MAX limits and
   prevents V8 from holding the prompt buffer twice (once in argv, once
   in the readStdin/prompt path).

Adds 4 regression tests covering NODE_OPTIONS, stdio pipe mode, argv
cleanliness, and preservation of a caller-supplied NODE_OPTIONS.
@waleedkadous
Copy link
Copy Markdown
Contributor Author

Excellent fix — thank you for the tight, well-scoped diagnosis and the two-pronged mitigation.

Architect integration review: APPROVE (HIGH confidence, no critical issues).

A couple of non-blocking notes for your awareness (no action needed):

  • The stdinPayload pattern is nicely extensible — if another CLI model (e.g. hermes) ever needs stdin piping, the mechanism is already in place.
  • The fix relies on gemini-cli's non-interactive stdin mode, which you verified manually. Worth remembering on future gemini-cli upgrades — a quick smoke test will confirm that assumption still holds.
  • The 4 new tests duplicate some setup boilerplate, but that matches the surrounding file's style. Fine as-is.

Please merge.

@waleedkadous waleedkadous merged commit 89f362b into main Apr 18, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

consult: gemini crashes on large PR diffs (V8 heap exhaustion)

1 participant