[app][macOS] ChatGPT/Codex crashes (V8 OOM) and hangs in reading_mode::parse_distilled_html (web reader / DOM distiller)
What version of the Codex App are you using (From "About Codex" dialog)?
26.814.41407 (6720) — also reproduced on 26.810.52044 (6662)
What subscription do you have?
Pro
What platform is your computer?
Darwin 25.5.0 arm64 arm
macOS 26.5.1 (Build 25F80), Apple silicon (arm64), Mac16,10, 16 GB RAM
What issue are you seeing?
The desktop app repeatedly crashes and hangs while using the web-reading / "browse a page" feature.
Crash (7 reports over ~2 days). All are EXC_CRASH / SIGABRT with asi = "libsystem_c.dylib: abort() called". The abort is raised by Node/V8's out-of-memory handler. Triggered-thread stack (innermost first):
__pthread_kill
pthread_kill
abort
node::OOMErrorHandler(char const*, v8::OOMDetails const&)
reading_mode$cxxbridge1$194$parse_distilled_html + ...
reading_mode$cxxbridge1$194$parse_distilled_html + ...
v8::CppHeap::CollectGarbageInYoungGenerationForTesting(...)
...
v8::internal::StrongRootAllocatorBase::allocate_impl(...)
... (JIT frames) ...
v8::Function::Call
node::InternalMakeCallback
node::AsyncWrap::MakeCallback
node::worker::MessagePort::OnMessage
node::worker::Worker::Run
So a Node worker thread calls into the Rust reading_mode::parse_distilled_html, which allocates cppgc (Oilpan) objects; a cppgc collection runs, an allocation fails, and V8 aborts the process.
Hang (3 reports). The process becomes unresponsive for ~40-50 seconds. The busy thread is stuck 15/15 samples in:
reading_mode$cxxbridge1$194$parse_distilled_html +11369892
cppgc::internal::BaseObjectSizeTrait::GetObjectSizeForGarbageCollected
At hang time the footprint is only ~827 MB, so this is not a whole-machine OOM — it is cppgc heap exhaustion / a pathological GC pass. The process also reports "Dispatch Thread Soft Limit Reached: 64" and "Workqueue exceeded constrained thread limit (64)" with 147 threads.
What steps can reproduce the bug?
- Open the ChatGPT/Codex desktop app on macOS.
- Ask it to read / summarize a web page (or use Browse on a large or complex page).
- The app either freezes for ~40-50s (beachball) or exits with a SIGABRT crash report.
What is the expected behavior?
Reading a web page should complete (or fail gracefully) without freezing the UI or crashing the app.
Additional information
- The
reading_modesymbols correspond to Chromium's DOM Distiller / Reader Mode:reading_mode.mojom.DistillationEvaluator,chrome-distiller,use_distiller,enable-dom-distiller,reader-mode-readability-distiller-enabled. - Root cause appears to be the Rust
reading_mode::parse_distilled_html+ cppgc (Blink Oilpan) integration building an unbounded object graph for certain pages, causing either cppgc OOM (crash) or a stuck GC pass (hang). - Local crash logs: ~/Library/Logs/DiagnosticReports/ChatGPT-.ips and /Library/Logs/DiagnosticReports/ChatGPT__longde.hang.
- Possibly related: issue #33582 (memory growth / system freeze) and the community thread "ChatGPT Desktop 26.810.50856 crashes after 1-3 minutes — computer-use / sky.node thread exhaustion".
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Update: still reproduces after clearing user state (sidebar page states + deepseek threads).
Additional evidence from a post-cleanup macOS hang report (process becomes unresponsive ~44s after launch, on every launch):
-[NSApplication run] -> CFRunLoop source0 -> JS callback -> reading_mode$cxxbridge1$194$parse_distilled_html -> cppgc::internal::BaseObjectSizeTrait::GetObjectSizeForGarbageCollected
So the distiller (Chromium DOM Distiller, via the Rust reading_mode crate) hangs in cppgc GC on the main thread at startup, independent of user data.
Update: I found a reproducible local trigger and a workaround that stopped the failure loop.
This changes my earlier assessment slightly:
reading_mode::parse_distilled_htmlremains the confirmed OOM/hang site, but the immediate resource explosion on this machine was associated with repeated managed Computer Use service launches.Trigger
The app itself is installed on the internal disk, but
~/.codexwas a symlink to a Codex home on an external APFS volume.CODEX_HOMEwas unset, so different parts of the app could refer to the same Computer Use runtime using two path spellings:During failure, the app launched hundreds of
SkyComputerUseServiceinstances within roughly a minute, alongside repeated socket-lock failures, AppleEvent-600failures, and eventual V8 OOM.Verified workaround
After fully quitting ChatGPT, I set
CODEX_HOMEto the canonical physical directory and relaunched:Across repeated samples covering the previous failure window,
SkyComputerUseServiceremained at one process and the socket-lock / AppleEvent / spawn-loop messages stopped.For Finder/Dock launches on macOS, a shell startup-file export is not sufficient; the GUI launch environment must receive the variable. If the canonical directory is on an external volume, it must be mounted before ChatGPT starts.
Likely mechanism
Inspection of the installed bundle suggests inconsistent path canonicalization around the managed Computer Use service. If ownership or PID validation compares the symlink spelling with the resolved spelling literally, a healthy child can be rejected and another service spawned.
Potential upstream hardening:
This is a locally verified workaround, not an upstream-confirmed root cause, and it may not explain every
reading_modeOOM. The distiller may still have an independent memory bug. It may explain one trigger behind the same crash family reported in #38867; #38566 may be a different failure mode.One investigation-process note, since credit is due: I had previously spent substantial time testing hypotheses with DeepSeek V4 Pro and DeepSeek V4 Flash, but those attempts did not isolate this trigger. ChatGPT/Codex was the tool that connected the Computer Use process storm to canonical
CODEX_HOMEpath identity and then validated the workaround with a controlled A/B test.