Skip to content

Renderer stack-overflow crash after grep tool fan-out exhausts memory (STATUS_COMMITMENT_LIMIT → STATUS_STACK_OVERFLOW) — v1.18.32 Windows #50596

Closed as not planned

Description

@jgrove255

Title

Desktop v1.18.32 (Windows): concurrent grep fan-out causes system OOM (ripgrep STATUS_COMMITMENT_LIMIT 0xC000012D), tools stuck "running", then renderer hangs and crashes with STATUS_STACK_OVERFLOW (0xC00000FD)

Description

Summary

On Windows, a single assistant message launched a large batch of concurrent
grep tool calls. Within seconds the host hit the Windows commit limit:
24 greps failed with Rust OOM / STATUS_COMMITMENT_LIMIT, ~283 tool parts
were left permanently status: "running", and the renderer logged a flood
of ResizeObserver errors before becoming unresponsive and dying with a
native stack overflow.

Environment

Field Value
App OpenCode Desktop 1.18.32 (packaged)
OS Windows 11 Home build 26200, win32 x64
Electron 42.3.3 (Chrome 148, Node 24.15.0)
Crash 2026-09-22 05:36:32 local — exitCode -1073741571 = 0xC00000FD STATUS_STACK_OVERFLOW

Host resources

Field Value
Machine Lenovo laptop (model 83D4)
CPU Intel Core Ultra 9 185H — 16 cores / 22 logical processors
RAM 32 GB physical (~31.6 GiB reported by Windows)
Page file System-managed (AutomaticManagedPagefile=True); after reboot Windows reports ~5.4 GB allocated (pagefile.sys)
Commit limit (post-reboot sample) ~36.9 GB (39 583 080 448 bytes)

Why this matters: STATUS_COMMITMENT_LIMIT (0xC000012D) is hit when the
commit charge (all private committed memory + page file) reaches the
system commit limit — not when free RAM alone is low. On this host the commit
limit is roughly RAM + page file (~32 GB + ~5 GB ≈ ~37 GB). A burst of
concurrent ripgrep processes each attempting large allocations (failures in
this report include ~137 MB and ~410 MB single allocations) plus the
Electron main/renderer processes and the opencode server can exhaust that
budget even though the machine has 32 GB of RAM.

Page-file figures above are a post-reboot sample (the machine had to be
hard-reset after this incident); they are not a live capture from the failure
moment. Peak commit at crash was not recorded.

A machine with more RAM and/or a larger page file would raise the commit
limit and may only delay the same failure — the fix is bounding concurrent
tool subprocesses / failing them cleanly, not requiring bigger hardware.

Timeline (local time)

Time Event
05:26:03 Session created; tools start
05:26:12 – 05:31:23 Renderer: 659× ResizeObserver loop completed with undelivered notifications
05:31:41 – 05:32:05 24 parallel greps fail in one assistant message
05:33:37 – 05:33:41 Server log re-evaluates the same 4 grep patterns in a tight loop (~50–100 ms apart)
05:33:41 Last tool end timestamp; 283 tool parts still "running" with no end time
05:35:18 / 05:35:48 renderer unresponsive (oc://renderer/index.html)
05:36:32 app render process gone { reason: 'crashed', exitCode: -1073741571 }

Tool failure statistics (from session export)

  • 437 tool parts total (364 grep, 41 read, 16 glob, 9 edit, 7 bash)
  • 24 tool parts with status: "error" — all grep, all in one burst (~25 s)
  • 283 tool parts left status: "running" (no time.end) when the session was exported mid-failure

Error breakdown (24 failures):

Count Error
22 memory allocation of N bytes failed — allocation sizes ranged from ~14 KB to ~410 MB (e.g. 14 848, 29 696, 47 775 744, 143 327 232, 429 981 696 bytes)
1 Rust panic: failed to spawn thread: Os { code: 1450, … "Insufficient system resources exist to complete the requested service." } (library/std/src/thread/scoped.rs:199)
1 ripgrep failed with code 3221225773 = 0xC000012D STATUS_COMMITMENT_LIMIT

Representative failed tool state (same assistant message, ~05:31:41–05:32:05):

{
  "tool": "grep",
  "state": {
    "status": "error",
    "input": { "path": "<project-subdir>", "pattern": "<alternation regex>" },
    "error": "memory allocation of 14848 bytes failed",
    "time": { "start": 1790069501145, "end": 1790069528229 }
  }
}
{
  "tool": "grep",
  "state": {
    "status": "error",
    "input": { "path": "<project-file.md>", "pattern": "<alternation regex>" },
    "error": "ripgrep failed with code 3221225773",
    "time": { "start": 1790069525668, "end": 1790069619938 }
  }
}

Four grep patterns were retried repeatedly across the burst (also visible
as back-to-back evaluated permission=grep lines in the server log every
~50–100 ms during 05:33:37–05:33:41). Example shapes (content redacted):

  • word A|word B (two-term alternation)
  • phrase|other-phrase|third-phrase (three-term alternation)
  • prefix|prefix.*suffix|literal (one .* regex term)
  • token;|token save (semicolon / short-token alternation)

Failed greps and successful greps interleaved in the same burst — some
children completed while others OOM’d, consistent with host-wide commit
pressure rather than a single bad pattern.

Renderer / crash evidence

[05:35:18] renderer unresponsive { currentURL: 'oc://renderer/index.html' }
[05:35:48] renderer unresponsive { … }
[05:36:32] app render process gone {
  url: 'oc://renderer/index.html',
  details: { reason: 'crashed', exitCode: -1073741571 }   // 0xC00000FD STATUS_STACK_OVERFLOW
}

renderer.log: 659× ResizeObserver loop completed with undelivered notifications.
between 05:26:12 and 05:31:23 (same window as the session’s tool storm).

Related (earlier session, same day)

Prior session (05:15:38–05:15:39): 314×

TypeError [ERR_INVALID_STATE]: Invalid state: Controller is already closed
  at ReadableStreamDefaultController.enqueue
  at …/node-D4_KoIXC.js:434893:45

Unhandled rejection ids reached 719; sidecar exited code: 0 at 05:16:00.
Likely a separate stream-lifecycle bug; not required to reproduce the crash
but worth tracking on its own.

Suspected mechanism

  1. One assistant step issues many concurrent grep tool calls (dozens in one message; 24 started within ~25 s).
  2. On a 32 GB / ~5 GB page-file host, concurrent ripgrep allocations plus app processes push commit charge to the Windows commit limit → ripgrep dies with
    STATUS_COMMITMENT_LIMIT (0xC000012D) / Rust OOM / cannot spawn threads (Win32 1450).
  3. Tool runner never reaps/fails the rest → hundreds of tools stuck "running";
    permission evaluation keeps re-issuing the same patterns (server log tight loop).
  4. Renderer keeps receiving update storms → sustained ResizeObserver errors →
    hang → stack overflow crash (0xC00000FD).

Expected behavior

  • Cap concurrent tool subprocesses (or serialize greps) so one agent step cannot drive the machine to STATUS_COMMITMENT_LIMIT.
  • On child OOM / non-zero ripgrep exit, fail the tool promptly; do not leave parts "running" indefinitely; surface a clear error and stop retrying the same batch.
  • Renderer should throttle/coalesce tool-update UI work so it cannot hang or stack-overflow under update floods.

Actual behavior

Commit-limit OOM in grep/ripgrep → tool state left with ~283 parts stuck "running" → renderer unresponsive → process dies with STATUS_STACK_OVERFLOW.

Steps to reproduce (best effort)

  1. Open OpenCode Desktop 1.18.32 on Windows.
  2. Run an agent step that issues a large parallel batch of grep tools (24+ greps started within ~25 s in one message in this report).
  3. Observe: greps fail with memory allocation … failed / ripgrep failed with code 3221225773; tools remain running; renderer floods ResizeObserver errors then hangs and crashes (exitCode -1073741571).

Notes for maintainers

  • Exit-code math: -1073741571 = 0xC00000FD (STATUS_STACK_OVERFLOW); ripgrep exit 3221225773 = 0xC000012D (STATUS_COMMITMENT_LIMIT); Win32 1450 = ERROR_NO_SYSTEM_RESOURCES.
  • Host is not a low-memory edge case: 32 GB RAM / Ultra 9 185H. The failure is parallel tool fan-out vs commit limit, not a “needs more RAM” machine.

Activity

  1. github-actions commented on Sep 22, 2026

    @github-actions
    Contributor

    This issue might be related to existing issues. Please check:

    Your report adds valuable new evidence: concrete exit-code diagnostics for the renderer crash, the tool-state leak (283 parts stuck running), and the permission-evaluation tight-loop observed in server logs. That makes it worth keeping open independently even if the fix overlaps with #50563.

  2. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions