macOS desktop startup crash when a rollout JSONL contains a huge single line
What version of Codex is running?
Codex.app 26.318.11754 (CFBundleVersion 1100)
Installed via Homebrew cask: brew install --cask codex-app
Which model were you using?
Unknown / not relevant. This happens during desktop app startup before normal use.
What platform is your computer?
macOS 26.3.1 (25D2128) on arm64
What steps can reproduce the bug?
- Have a
rollout-*.jsonlfile under~/.codex/sessions/...with one extremely large line. - Launch the Codex macOS desktop app.
- The app fails during startup with a main-process JavaScript exception.
Observed dialog / stack:
A JavaScript error occurred in the main process
Uncaught Exception:
RangeError: Invalid string length
at [_normalWrite] [as _normalWrite] (node:internal/readline/interface:652:31)
at ReadStream.ondata (node:internal/readline/interface:263:23)
at ReadStream.emit (node:events:508:28)
at addChunk (node:internal/streams/readable:559:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
at Readable.push (node:internal/streams/readable:390:5)
at node:internal/fs/streams:292:14
at FSReqCallback.wrapper [as oncomplete] (node:fs:670:5)
What did you expect to happen?
Startup should not crash because of a malformed or oversized rollout log.
The app should skip the file, cap line size, or parse it using a streaming approach that does not let readline accumulate an arbitrarily large line in memory.
Additional context
I traced the crash to desktop startup scanning rollout logs for rollout metrics.
The shipped app bundle appears to read rollout-*.jsonl via readline.createInterface(...) during startup.
The file that triggered it on my machine was:
~/.codex/sessions/2026/03/21/rollout-2026-03-21T21-11-23-019d11cf-2c7f-7341-8228-c44709509ba4.jsonl
Its characteristics were:
- file size:
539303205bytes - line count:
203 - largest line: about
538928628bytes on line17
I independently reproduced the exact same RangeError outside the app by running Node readline against that file.
Workaround
Moving the bad rollout file out of ~/.codex/sessions allowed Codex Desktop to start normally again.
Example workaround:
mkdir -p ~/.codex/quarantine
mv ~/.codex/sessions/2026/03/21/rollout-2026-03-21T21-11-23-019d11cf-2c7f-7341-8228-c44709509ba4.jsonl \
~/.codex/quarantine/rollout-2026-03-21T21-11-23-019d11cf-2c7f-7341-8228-c44709509ba4.jsonl.corrupt
Suggested fix
Any of these would avoid taking down the app on startup:
- refuse to parse rollout lines above a size cap
- skip malformed / oversized rollout logs during startup metrics aggregation
- avoid
readlinefor untrusted large JSONL and use a bounded streaming parser - isolate rollout metrics parsing so a single bad file cannot crash the main process
2 Comments
Reproduced on macOS Intel with the current desktop app, and I have an additional signal about how the bad file was produced.
Environment:
26.415.21839(CFBundleVersion1763)41.2.0v24.14.0buffer.constants.MAX_STRING_LENGTH = 53687088815.7.4on Intel (x64)Observed startup error matches this issue:
Local triggering file:
Its characteristics:
565M542591055538bytes on line15That largest line is above Node/V8's max string length on this build (
536870888), soreadlineblows up when startup scans the file.Additional useful signal:
.codex/sessions/YYYY/MM/DD/*.jsonllogscodesign/NordVPN helper/ keychain-related issue, and the huge record seems to be an aggregated search/output payload from that log-inspection taskSo this looks broader than “one malformed rollout line from model output”:
The
RangeError: Invalid string lengthin node's readline is the tell — readline materializes each line as a single JS string, and one oversized line (almost always a base64-inlined image or a giant tool output) exceeds the string length limit and crashes the main process at startup, before the app can even decide to skip the file. The rollout isn't malformed per se; it's that one record is too large for the line-based reader.The safe handling is to not read line-by-line into memory: cap line size, stream-parse with a bounded buffer, or skip-and-quarantine the oversized record so startup survives. For anyone blocked, the immediate question is which record is oversized and how much of the file it accounts for — that determines whether the session is salvageable minus that one payload.
Full disclosure: I maintain codex-rescue (https://github.com/shleder/codex-rescue).
codex-rescue doctor --latestclassifies oversized/malformed records andstorageprofiles per-record byte distribution read-only, so you can pinpoint the single huge line and quantify how much of the rollout it dominates without loading the whole file into memory. That tells you whether stripping that one payload recovers the rest of the transcript.