openclaw - 💡(How to fix) Fix Windows: CLI crashes with stack overflow / heap OOM on v2026.4.5 (large ESM module graph exceeds V8 default stack) [1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#62055Fetched 2026-04-08 03:09:37
View on GitHub
Comments
1
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
commented ×1

On Windows, openclaw dashboard (and likely other heavy commands) crashes with either:

  1. RangeError: Maximum call stack size exceeded during ESM module evaluation, or
  2. FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory after prolonged startup

Both are caused by the same root issue: Windows V8 default stack size (~1 MB) is insufficient for the CLI's large ESM module graph.

Error Message

e:...\dist\ollama-runtime.js:9 RangeError: Maximum call stack size exceeded at evaluateSync (node:internal/modules/esm/module_job:458:26)

Root Cause

Windows V8 default stack is ~1 MB (vs ~8 MB on macOS/Linux). The CLI's module graph has grown significantly between v2026.4.2 and v2026.4.5:

  • dist/register.maintenance.js (loaded for dashboard, doctor, reset, uninstall) pulls in 326 transitive static imports across 19 levels of depth.
  • On macOS/Linux the 8 MB stack handles this fine. On Windows, the ~1 MB default overflows during V8's evaluateSync phase of ESM module loading.

Contributing factors (all required to trigger):

  1. Large ESM import graph — 326 modules for maintenance commands
  2. CLI async call chain depth — Commander.js action handlers add several frames before the dynamic import() of register.maintenance.js
  3. process.argv[1] pointing to dist/entry.js — captured at module-eval time by STARTUP_ARGV1 in sdk-alias.js, subtly increasing per-frame stack usage during path resolution
  4. Windows V8 stack default — ~1 MB vs 8 MB on other platforms

Systematic proof: Through controlled experiments with wrapper scripts, we confirmed:

  • node --stack-size=16384 dist/entry.js dashboardworks (no crash)
  • Shallow call stack + same imports → works (not enough depth)
  • Deep call stack + process.argv[1] not pointing to dist + same imports → works
  • Deep call stack + process.argv[1] pointing to dist + same imports → crashes
  • Pre-importing all 326 modules first, then executing → works (modules already cached)

Fix Action

Fix / Workaround

Crash variant 2 — Heap OOM (after stack-size workaround):

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
[19976:00000207AF401000] 96332 ms: Mark-Compact 4085.9 (4116.4) -> 4082.6 (4119.1) MB

Code Example

npm i -g openclaw@2026.4.5
openclaw dashboard

---

e:\...\dist\ollama-runtime.js:9
RangeError: Maximum call stack size exceeded
    at evaluateSync (node:internal/modules/esm/module_job:458:26)

---

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
[19976:00000207AF401000] 96332 ms: Mark-Compact 4085.9 (4116.4) -> 4082.6 (4119.1) MB

---

// Windows has a ~1MB default V8 stack which overflows during ESM module evaluation
// of the full CLI import graph. Bump to 8MB (matching macOS/Linux defaults).
if (
  process.platform === "win32" &&
  !childExecArgv.some((arg) => arg.startsWith("--stack-size"))
) {
  childExecArgv.unshift("--stack-size=8192");
  needsRespawn = true;
}
RAW_BUFFERClick to expand / collapse

Bug: Windows crashes on CLI startup (stack overflow + heap OOM)

Summary

On Windows, openclaw dashboard (and likely other heavy commands) crashes with either:

  1. RangeError: Maximum call stack size exceeded during ESM module evaluation, or
  2. FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory after prolonged startup

Both are caused by the same root issue: Windows V8 default stack size (~1 MB) is insufficient for the CLI's large ESM module graph.

Environment

  • OS: Windows 11 (10.0.22631), AMD64
  • Node.js: v22.19.0
  • OpenClaw: v2026.4.5 (regression introduced in this release)
  • Last working release: v2026.4.2

Steps to Reproduce

npm i -g [email protected]
openclaw dashboard

Expected Behavior

Dashboard starts normally.

Actual Behavior

Crash variant 1 — Stack overflow:

e:\...\dist\ollama-runtime.js:9
RangeError: Maximum call stack size exceeded
    at evaluateSync (node:internal/modules/esm/module_job:458:26)

Crash variant 2 — Heap OOM (after stack-size workaround):

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
[19976:00000207AF401000] 96332 ms: Mark-Compact 4085.9 (4116.4) -> 4082.6 (4119.1) MB

Root Cause Analysis

Windows V8 default stack is ~1 MB (vs ~8 MB on macOS/Linux). The CLI's module graph has grown significantly between v2026.4.2 and v2026.4.5:

  • dist/register.maintenance.js (loaded for dashboard, doctor, reset, uninstall) pulls in 326 transitive static imports across 19 levels of depth.
  • On macOS/Linux the 8 MB stack handles this fine. On Windows, the ~1 MB default overflows during V8's evaluateSync phase of ESM module loading.

Contributing factors (all required to trigger):

  1. Large ESM import graph — 326 modules for maintenance commands
  2. CLI async call chain depth — Commander.js action handlers add several frames before the dynamic import() of register.maintenance.js
  3. process.argv[1] pointing to dist/entry.js — captured at module-eval time by STARTUP_ARGV1 in sdk-alias.js, subtly increasing per-frame stack usage during path resolution
  4. Windows V8 stack default — ~1 MB vs 8 MB on other platforms

Systematic proof: Through controlled experiments with wrapper scripts, we confirmed:

  • node --stack-size=16384 dist/entry.js dashboardworks (no crash)
  • Shallow call stack + same imports → works (not enough depth)
  • Deep call stack + process.argv[1] not pointing to dist + same imports → works
  • Deep call stack + process.argv[1] pointing to dist + same imports → crashes
  • Pre-importing all 326 modules first, then executing → works (modules already cached)

Proposed Fix

Add a Windows-specific --stack-size=8192 flag to the CLI's existing process respawn mechanism in src/entry.respawn.ts:

// Windows has a ~1MB default V8 stack which overflows during ESM module evaluation
// of the full CLI import graph. Bump to 8MB (matching macOS/Linux defaults).
if (
  process.platform === "win32" &&
  !childExecArgv.some((arg) => arg.startsWith("--stack-size"))
) {
  childExecArgv.unshift("--stack-size=8192");
  needsRespawn = true;
}

This slots naturally into buildCliRespawnPlan() alongside the existing ExperimentalWarning and CA cert respawn conditions. The respawn mechanism already exists and is well-tested — this just adds one more condition for Windows.

Additional Notes

  • v2026.4.2 does not crash on Windows — the module graph was small enough
  • The growth between v2026.4.2 and v2026.4.5 (new anthropic transport, refactored streaming, etc.) pushed the graph past the Windows threshold
  • This will likely recur if the module graph grows further, but 8 MB provides substantial headroom (matching what macOS/Linux provide by default)
  • Long-term, consider lazy-loading or code-splitting the heaviest import subgraphs (e.g., the 326-module maintenance registration)

extent analysis

TL;DR

Increase the stack size for Windows to prevent crashes during CLI startup by adding a --stack-size=8192 flag.

Guidance

  • Identify if the crash is due to a stack overflow or heap out of memory error, and verify that the issue is specific to Windows.
  • Apply the proposed fix by adding the --stack-size=8192 flag to the CLI's process respawn mechanism in src/entry.respawn.ts for Windows platforms.
  • Test the fix by running the CLI with the updated flag and verify that it no longer crashes.
  • Consider long-term solutions such as lazy-loading or code-splitting the heaviest import subgraphs to prevent future crashes.

Example

The proposed fix can be implemented in src/entry.respawn.ts as follows:

if (
  process.platform === "win32" &&
  !childExecArgv.some((arg) => arg.startsWith("--stack-size"))
) {
  childExecArgv.unshift("--stack-size=8192");
  needsRespawn = true;
}

Notes

This fix provides a temporary solution to increase the stack size for Windows, but it may need to be revisited if the module graph continues to grow.

Recommendation

Apply the workaround by adding the --stack-size=8192 flag to the CLI's process respawn mechanism, as it provides a straightforward solution to prevent crashes on Windows.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING