[macOS][Codex Desktop] Chrome rollout tracker loops at >160% CPU when session JSONL exceeds V8 max string length

Open 💬 2 comments Opened Aug 14, 2026 by perhapseb

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

  1. Keep a Codex Desktop task active long enough that its ~/.codex/sessions/.../rollout-*.jsonl grows beyond Node/V8's maximum string length.
  2. Initialize the bundled Chrome-control browser runtime in that task.
  3. The rollout tracker discovers the current session file with fileOffset = 0.
  4. It reads the entire rollout in 64 KiB chunks, concatenates those buffers, and calls .toString("utf8").
  5. Conversion fails before the returned offset can be assigned.
  6. 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,430 bytes
  • Bundled Node buffer.constants.MAX_STRING_LENGTH: 536,870,888 bytes
  • JSONL records: 24,675
  • compacted records: 35 records totaling 828,221,910 bytes
  • Largest individual record: 33,878,758 bytes
  • 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 fileOffset only 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.

View original on GitHub ↗

2 Comments

perhapseb · 13 days ago

Private in-app diagnostics have now been submitted from the affected task with both current session logs and browser tabs/browser logs included.

Feedback ID: 019fdd30-fe5e-75d0-b47e-2d6178bde306

This identifier also corresponds to the affected Codex task referenced in the report, which should help correlate the uploaded diagnostics with the oversized rollout and Chrome-helper reproduction.

shleder · 13 days ago

A ~1.15 GB rollout with a >33 MB individual record is a useful scale case for Codex Rescue. Its discovery/doctor path is intended to stay bounded and never load or mutate the whole rollout.

If you still have that exact session and are comfortable testing a third-party local tool, could you try:

pipx install codex-rescue==0.1.0a3
codex-rescue sessions --limit 1000
codex-rescue doctor --latest

Only use --latest if the affected rollout is still the latest one; otherwise select it locally from sessions without posting its ID/path. No salvage needed.

I’m mainly interested in whether the run stays bounded and whether it reports the oversized persisted payload conservatively. Sanitized status/findings and rough runtime are enough — no raw history, image/base64 data, prompts, paths, IDs, repository content, or secrets.

https://github.com/shleder/codex-rescue