[macOS][Codex Desktop] Chrome rollout tracker loops at >160% CPU when session JSONL exceeds V8 max string length
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
Codex app version
26.803.61601 (build 6396)
Platform
macOS 27.0 beta (26A5388g), Apple Silicon
Summary
The bundled Chrome-control browser-client.mjs rollout tracker enters a permanent high-CPU/high-allocation retry loop when it attaches to a long-running Codex Desktop task whose rollout JSONL exceeds V8's maximum JavaScript string length.
The observed task remained active and usable, but the Chrome-control Node helper sustained approximately 160-167% CPU until terminated.
Reproduction conditions
- Keep a Codex Desktop task active long enough that its
~/.codex/sessions/.../rollout-*.jsonlgrows beyond Node/V8's maximum string length. - Initialize the bundled Chrome-control browser runtime in that task.
- The rollout tracker discovers the current session file with
fileOffset = 0. - It reads the entire rollout in 64 KiB chunks, concatenates those buffers, and calls
.toString("utf8"). - Conversion fails before the returned offset can be assigned.
- The tracker catches the failure without disabling tracking or advancing the offset, then polls again after 250 ms and repeats from byte zero.
Sanitized measurements from the affected task
- Rollout JSONL size:
1,148,831,430bytes - Bundled Node
buffer.constants.MAX_STRING_LENGTH:536,870,888bytes - JSONL records:
24,675 compactedrecords: 35 records totaling828,221,910bytes- Largest individual record:
33,878,758bytes - Hot helper CPU: approximately
160-167% - Current helper RSS during sampling: approximately
3.8 GiB - Physical-footprint peak:
12.1 GiB - Native stack sample was dominated by asynchronous filesystem reads, ArrayBuffer allocation, and V8 garbage collection.
- The helper held the same rollout file open twice during the loop.
- No macOS thermal or performance warning was reported.
No private task history or browser data is attached.
Relevant installed-runtime behavior
The bundled tracker:
- polls every 250 ms while a rollout is active;
- starts newly discovered sessions at offset zero;
- reads all remaining bytes into an array of 64 KiB buffers;
- concatenates all buffers and converts them into one UTF-8 string;
- updates
fileOffsetonly after that operation returns successfully; - catches processing errors and leaves polling active.
Because the observed rollout is more than twice MAX_STRING_LENGTH, the initial conversion cannot succeed. The saved offset therefore remains zero and each poll repeats the full read/allocation attempt.
Expected behavior
Rollout tracking should remain bounded regardless of task-history size. For example:
- tail only a bounded recent portion when attaching to an existing rollout;
- stream JSONL incrementally rather than materializing it as one string;
- cap each read/parse batch;
- advance or checkpoint the offset safely;
- stop retrying or disable tracking after an unrecoverable size error;
- surface a useful diagnostic instead of swallowing the failure.
Actual behavior
One Chrome-control helper continuously rereads and reallocates the oversized rollout, consuming more than one CPU core and several GiB of memory even after browser operations have finished.
Related issues
- #21134 — long active desktop threads causing CPU/memory degradation
- #18629 — inline browser images inflating/poisoning desktop thread histories
Those reports describe related history growth and long-thread degradation, but not this specific rollout-tracker string-limit retry loop.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the bundled Chrome-control browser-client.mjs rollout tracker and trace session discovery, 64 KiB reads, UTF-8 conversion, fileOffset updates, and error handling. Reproduce with a rollout JSONL larger than V8's MAX_STRING_LENGTH, then verify that tracking stays bounded, does not reread the file indefinitely, and surfaces a useful diagnostic or stops safely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, macos, node.js
- Domain
- desktop, devtools, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100