Summary
Codex desktop crashed twice while its in-app browser was opening the same private
TerraMaster TOS 7.0 administrative page. The page initially looked responsible,
but local logs, Windows crash events, a minidump and inspection of the installed
Codex package point to an unrelated native module bundled with Codex:
@worklouder/device-kit-oai 0.1.10
└─ @worklouder/wl-device-kit 0.1.18
└─ serialport 12.0.0
└─ @serialport/bindings-cpp 12.0.1
└─ build/Release/serialport.node
serialport.node fails during initialization because its delayed import cannot
resolve node.exe!napi_module_register. Codex records the resulting DLL error as
an unhandled rejection, and Windows records exception 0xc06d007f at the same
fault offset each time.
The evidence does not identify any HTML, JavaScript or network response on
the TOS page that directly triggers the native fault. The page appears to be a
reliable reproduction target, while browser/session initialization appears to
expose a Codex native-addon packaging or load-hook problem.
Impact
- The active Codex task was interrupted and the desktop app had to recover or
restart. - The original Codex browser-control path reproduced the user-visible failure
twice in two attempts. - Windows logged additional identical application-error events while the issue
was being diagnosed.
Environment
| Property | Value |
|---|---|
| Codex desktop | 26.707.9981.0 |
| Package | OpenAI.Codex, x64, MSIX status OK |
| Operating system | Windows 11 Home 25H2, x64 |
| OS build | 26200.8655 |
| Target page | Private TerraMaster TOS 7.0 page over plain HTTP; hostname redacted |
Steps to reproduce
- Open Codex desktop on Windows.
- In a Codex task, initialize the in-app browser-control integration.
- Create a browser tab and navigate it to a private TOS page such as
http://<private-nas-host>:8181/. - Wait for
DOMContentLoadedand request a DOM snapshot. - Observe Codex become unavailable, interrupt the task or restart.
- Repeat the same sequence. It reproduced twice during the original task.
The target redirects to /tos/#/ and displays the title TOS 7.0.
Expected behavior
The page should open in the in-app browser. A failure in an optional hardware
integration should be caught and isolated from browser control and from the
Codex desktop process.
Actual behavior
Codex crashes or interrupts the task while the page is loading or being
inspected. The Codex desktop log reports an unhandled native-module load error:
[electron-message-handler] [desktop-notifications][unhandled-rejection]
Error: A dynamic link library (DLL) initialization routine failed.
...\@worklouder\device-kit-oai\node_modules\@worklouder\wl-device-kit\
node_modules\serialport\node_modules\@serialport\bindings-cpp\
build\Release\serialport.node
The desktop-notifications label is present in the log, but the referenced
binary and the installed package’s load chain point to the Codex Micro/Work
Louder device integration.
Windows crash signature
Windows Application Error event 1000 repeatedly reports:
Faulting application: ChatGPT.exe
Package: OpenAI.Codex_26.707.9981.0_x64__2p2nqsd0c76g0
Exception code: 0xc06d007f
Fault offset: 0x00007fff58281b6a
Faulting module: unknown
During the investigation, Windows recorded 38 events with the same exception
code and fault offset between 3:15 p.m. and 4:11 p.m. local time on July 15,
2026. Not every event produced a separately observed full-app restart, but the
signature is consistent across the user-visible failures and diagnostic runs.
Minidump evidence
A Windows minidump from ChatGPT.exe shows:
serialport.nodewas loaded from the Work Louder dependency tree inside the
Codex MSIX package.- The exception address is in
KernelBase.dll. - The exception code is the Microsoft C++ delay-load exception carrying status
0x7f, orERROR_PROC_NOT_FOUND. - The
DelayLoadInfostructure identifies the delayed-import target as
node.exeand the missing procedure asnapi_module_register.
This establishes the native load failure. It does not by itself establish
whether the final process termination is caused by Electron’s handling of that
exception, the unhandled rejected promise or a second failure afterward.
Installed-package evidence
The installed app.asar contains a dedicated Codex Micro service. Its packaged
code does the following:
CodexMicroService.getState()dynamically loads
@worklouder/device-kit-oai.- Starting that service begins Work Louder hardware discovery.
device-kit-oaiimports@worklouder/wl-device-kit.- The base device kit eagerly requires both
node-hidandserialport. - Loading SerialPort reaches the failing
serialport.nodebinary.
The Work Louder packages and native binary are part of the installed Codex
application. They are not supplied by the TOS page.
Page investigation
I tested the redacted TOS URL separately in an isolated Playwright Chromium
session. It loaded successfully and did not crash the browser.
Observed page behavior:
- The page is a Vue single-page application served over plain HTTP.
- It redirects to
/tos/#/and rendersTOS 7.0. - The browser console contained zero errors and zero warnings.
- Initial dynamic API and asset requests completed with HTTP 200 responses.
- The page contained no iframes and did not register a service worker.
- Because the page is an insecure context, Web Serial, WebHID, WebUSB and Web
Bluetooth were unavailable. - Static scans of the base bundles and dynamically loaded login chunks found no
calls tonavigator.serial,navigator.hid,navigator.usbor
navigator.bluetooth.
These results make a page-script request for physical-device access an unlikely
explanation. The remaining correlation is the Codex in-app browser/session
lifecycle around the navigation, not a specific TOS page feature.
Root-cause assessment
Confirmed
- Codex bundles and loads the Work Louder device integration.
- That integration eagerly loads SerialPort’s native Windows addon.
- The native addon fails to resolve
napi_module_registerfrom its delayed
node.exeimport. - Codex logs the DLL initialization failure as an unhandled rejection.
- Windows crash events and dumps repeatedly show the same native exception.
Likely, but not yet confirmed
serialport.nodewas built or packaged incompatibly with the Electron/Node
runtime used by this Codex build, or its Windows delay-load hook is missing or
ineffective.- Browser/session initialization or a nearby renderer request causes Codex to
query Codex Micro device state, exposing the broken optional integration. - The private TOS URL affects timing or makes the problem easy to notice, but is
not the native root cause.
Suggested engineering checks
- Rebuild and test
@serialport/bindings-cppfor the exact Electron runtime in
Codex26.707.9981.0. - Verify the Windows native addon delay-load hook correctly resolves Node-API
symbols, includingnapi_module_register. - Do not eagerly load
node-hidorserialportwhen no Codex Micro hardware
feature is in use. Consider the device kit’s browser-safe entry point where
applicable. - Catch native-addon load failures at the Codex Micro service boundary and
return an unavailable-device state instead of an unhandled rejection. - Verify that browser-control initialization does not need to initialize the
unrelated physical-device service. - Add a Windows smoke test that starts Codex, initializes browser control and
opens a normal page on a machine without Work Louder hardware attached.
Workaround
Avoid the Codex in-app browser-control path on this build. The same page loaded
successfully in an isolated Playwright Chromium session, so external browser
automation is a viable temporary alternative.
Diagnostic files available privately
- Codex desktop log containing the DLL initialization error and in-app-browser
lifecycle events. - Windows Application Error event 1000 records.
- Multiple
ChatGPT.exeminidumps. - The exact two interrupted Codex task turns and browser-control command
sequence.
Minidumps and full desktop logs can contain private process memory, local paths,
task identifiers and private hostnames. I would provide them through a private
OpenAI support channel rather than attach them to a public forum post.