[GH-ISSUE #4806] [Bug] Default TOON output crashes with RangeError on a large resource_constraint that --format json returns #2498

Closed
opened 2026-10-17 21:05:46 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @JayOfTheKeyboard on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4806

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

On a large Electron app, analyze-javascript-application stops with a typed resource_constraint (the parent's result capacity is exhausted) that carries a partial observation of about 620 MB. With --format json the caller gets that error. With the default TOON format, rendering it crashes the CLI: Node prints an uncaught RangeError: Invalid string length from the TOON encoder and exits 1, and stdout is empty.

file:///.../node_modules/@toon-format/toon/dist/index.mjs:1906
	return Array.from(encodeLines(input, options)).join("\n");
	                                               ^

RangeError: Invalid string length
    at Array.join (<anonymous>)
    at encode (file:///.../node_modules/@toon-format/toon/dist/index.mjs:1906:49)
    at Module.format (file:///.../node_modules/incur/dist/Formatter.js:32:12)
    at write (file:///.../node_modules/incur/dist/Cli.js:1122:37)
    at serveImpl (file:///.../node_modules/incur/dist/Cli.js:1368:9)
    at async file:///.../scripts/rea.mjs:95:5

Node.js v24.18.0

#1371 fixed this for --format json, which now streams. TOON is the default, and yaml and md take the same path, so the default command still crashes. The same path renders successful results, so a large enough success should crash the same way, but I have only seen it with this error.

Reproduction

The target is Local 9.2.4 for Linux (WP Engine's free WordPress app). Its resources/app.asar is 135 MB with 19,896 entries.

rea analyze-javascript-application ./Local/resources/app.asar > result.toon
echo $?   # 1, after 1,351 s and 3.9 GiB peak RSS; result.toon is empty

rea analyze-javascript-application ./Local/resources/app.asar --format json > result.json
echo $?   # 1, after 1,473 s and 2.8 GiB peak RSS
head -c 200 result.json
# {"error":"JavaScript application analysis failed","code":"resource_constraint","category":"resource_constraint","message":"The parent's result capacity was exhausted after retaining static facts for node_modules/handlebars/dist/handlebars.amd.js; ...
wc -c < result.json   # 620456896

I could not get a small generated input past the limit: twelve generated 1.66 MB files gave the same 320 MB TOON result as six.

Expected behavior

The default format returns the same typed resource_constraint that --format json returns. If the full error cannot be rendered as text, a smaller typed error in the shape --token-count already uses in src/cli/cliResultOutput.ts (formatted size against constants.MAX_STRING_LENGTH, remediation pointing at --format json or --filter-output) would still tell the caller what happened.

Impact and scope

Default CLI runs of analyze-javascript-application on large Electron apps, and likely any command whose output passes about 512 MiB of TOON, YAML or Markdown text. The crash comes at the end, so the user waits through the whole analysis first (22.5 minutes here) and then gets no typed error to act on.

REA version

main at 2cf9c28f

Runtime and platform

Node 24.18.0, Fedora 44 x86_64

Target and artifact context

Local 9.2.4+6788 for Linux, unmodified app.asar copied out of /opt/Local/resources.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

A second TOON run with --integrity-policy record-and-continue crashed the same way after 1,675 s and 3.9 GiB peak RSS.

The JSON error reports parent_result_budget_bytes: 2005337492. V8's MAX_STRING_LENGTH is 536,870,888 characters. So the partial observation can fit the parent budget and still be too large to render as one TOON string.

Typed outcome or recovery expected

resource_constraint with resource: memory, the formatted size if it is known, max_string_characters, and a remediation that names --format json.

Analysis or suspected cause

createCliResultOutput in src/cli/cliResultOutput.ts returns false in any format other than json or jsonl unless --full-output is set (line 145), which hands rendering to Incur. Incur's write calls Formatter.format(base, format) on the result or the error (Cli.js:1122 in the trace), which builds the whole TOON document as one string.

Some options, all yours to choose:

  1. Catch a RangeError from that rendering at the CLI boundary and write the typed error. Incur adds cta and --token-limit truncation in the same call, so the catch has to wrap Incur's write or keep those behaviours.
  2. Estimate the size first, as the --token-count branch does with jsonOutputParts, and refuse before formatting. TOON is not the same length as JSON (Discord's result is 137 MB of TOON and 104 MB of JSON), so the estimate would need a margin.
  3. Stream TOON, YAML and Markdown as JSON is streamed.

Additional context

Related: #4797, the unbounded semantic unknowns that make these results so large. I can send a PR for whichever option you prefer.

Originally created by @JayOfTheKeyboard on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4806 ### Before submitting - [X] I searched the open and closed issues for a related report. - [X] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior On a large Electron app, `analyze-javascript-application` stops with a typed `resource_constraint` (the parent's result capacity is exhausted) that carries a partial observation of about 620 MB. With `--format json` the caller gets that error. With the default TOON format, rendering it crashes the CLI: Node prints an uncaught `RangeError: Invalid string length` from the TOON encoder and exits 1, and stdout is empty. ```text file:///.../node_modules/@toon-format/toon/dist/index.mjs:1906 return Array.from(encodeLines(input, options)).join("\n"); ^ RangeError: Invalid string length at Array.join (<anonymous>) at encode (file:///.../node_modules/@toon-format/toon/dist/index.mjs:1906:49) at Module.format (file:///.../node_modules/incur/dist/Formatter.js:32:12) at write (file:///.../node_modules/incur/dist/Cli.js:1122:37) at serveImpl (file:///.../node_modules/incur/dist/Cli.js:1368:9) at async file:///.../scripts/rea.mjs:95:5 Node.js v24.18.0 ``` #1371 fixed this for `--format json`, which now streams. TOON is the default, and `yaml` and `md` take the same path, so the default command still crashes. The same path renders successful results, so a large enough success should crash the same way, but I have only seen it with this error. ### Reproduction The target is Local 9.2.4 for Linux (WP Engine's free WordPress app). Its `resources/app.asar` is 135 MB with 19,896 entries. ```sh rea analyze-javascript-application ./Local/resources/app.asar > result.toon echo $? # 1, after 1,351 s and 3.9 GiB peak RSS; result.toon is empty rea analyze-javascript-application ./Local/resources/app.asar --format json > result.json echo $? # 1, after 1,473 s and 2.8 GiB peak RSS head -c 200 result.json # {"error":"JavaScript application analysis failed","code":"resource_constraint","category":"resource_constraint","message":"The parent's result capacity was exhausted after retaining static facts for node_modules/handlebars/dist/handlebars.amd.js; ... wc -c < result.json # 620456896 ``` I could not get a small generated input past the limit: twelve generated 1.66 MB files gave the same 320 MB TOON result as six. ### Expected behavior The default format returns the same typed `resource_constraint` that `--format json` returns. If the full error cannot be rendered as text, a smaller typed error in the shape `--token-count` already uses in `src/cli/cliResultOutput.ts` (formatted size against `constants.MAX_STRING_LENGTH`, remediation pointing at `--format json` or `--filter-output`) would still tell the caller what happened. ### Impact and scope Default CLI runs of `analyze-javascript-application` on large Electron apps, and likely any command whose output passes about 512 MiB of TOON, YAML or Markdown text. The crash comes at the end, so the user waits through the whole analysis first (22.5 minutes here) and then gets no typed error to act on. ### REA version main at 2cf9c28f ### Runtime and platform Node 24.18.0, Fedora 44 x86_64 ### Target and artifact context Local 9.2.4+6788 for Linux, unmodified `app.asar` copied out of `/opt/Local/resources`. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence A second TOON run with `--integrity-policy record-and-continue` crashed the same way after 1,675 s and 3.9 GiB peak RSS. The JSON error reports `parent_result_budget_bytes: 2005337492`. V8's `MAX_STRING_LENGTH` is 536,870,888 characters. So the partial observation can fit the parent budget and still be too large to render as one TOON string. ### Typed outcome or recovery expected `resource_constraint` with `resource: memory`, the formatted size if it is known, `max_string_characters`, and a remediation that names `--format json`. ### Analysis or suspected cause `createCliResultOutput` in `src/cli/cliResultOutput.ts` returns `false` in any format other than `json` or `jsonl` unless `--full-output` is set (line 145), which hands rendering to Incur. Incur's `write` calls `Formatter.format(base, format)` on the result or the error (`Cli.js:1122` in the trace), which builds the whole TOON document as one string. Some options, all yours to choose: 1. Catch a `RangeError` from that rendering at the CLI boundary and write the typed error. Incur adds `cta` and `--token-limit` truncation in the same call, so the catch has to wrap Incur's write or keep those behaviours. 2. Estimate the size first, as the `--token-count` branch does with `jsonOutputParts`, and refuse before formatting. TOON is not the same length as JSON (Discord's result is 137 MB of TOON and 104 MB of JSON), so the estimate would need a margin. 3. Stream TOON, YAML and Markdown as JSON is streamed. ### Additional context Related: #4797, the unbounded semantic unknowns that make these results so large. I can send a PR for whichever option you prefer.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2498
No description provided.