Fix: guard Owl feature-binding lookup so it fails safe on Linux - #7
Conversation
The bundled main-app chunk calls process._linkedBinding("electron_common_owl_features")
during startup to read OpenAI's internal feature-flag state. That binding only
exists in OpenAI's custom-patched Electron fork used for the official macOS/Windows
builds; the stock open-source Electron used here never has it, so the call throws
and bootstrap-import-main aborts on every single launch before the window ever
appears.
Guard the lookup so a missing binding degrades to "no Owl features enabled"
instead of crashing. The lookup lives in a content-hashed chunk file (not a fixed
path), so it's located by content rather than filename.
Verified: rebuilt the app, extracted the packed asar to confirm the guarded
fallback landed, then launched codex-app/start.sh directly — it now boots past
bootstrap, loads the webview UI, and connects to the app-server backend
(thread/list succeeds), instead of failing every time as before.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9882dab9f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| id: "linux-owl-feature-guard", | ||
| phase: "extracted-app", | ||
| order: 130, | ||
| ciPolicy: "optional", |
There was a problem hiding this comment.
Make the startup guard a required upstream patch
When an upstream bundle still references electron_common_owl_features but minifier drift prevents the exact replacement, the patch emits a warning and is recorded as skipped-optional; because this descriptor is optional, upstream validation still succeeds and can package an app that aborts every Linux launch on stock Electron. Since absence of this guard makes the application unusable, mark it required so bundle drift blocks the upstream build.
AGENTS.md reference: AGENTS.md:L198-L199
Useful? React with 👍 / 👎.
| } = require("../../../../bootstrap.js"); | ||
|
|
||
| module.exports = { | ||
| id: "linux-owl-feature-guard", |
There was a problem hiding this comment.
Add the descriptor to the expected core-patch list
Adding this discovered descriptor without updating expectedIds makes node --test scripts/patch-linux-window-ui.test.js fail in default core patch descriptors are grouped and unique, because the actual list now contains linux-owl-feature-guard while the expected list does not. This leaves the repository's documented patcher test suite—and the local core CI job that invokes it—failing for every run.
AGENTS.md reference: AGENTS.md:L70-L71
Useful? React with 👍 / 👎.
Summary
bootstrap-import-main, before the window ever appeared.process._linkedBinding("electron_common_owl_features")during startup to read OpenAI's internal feature-flag state. That native binding only exists in OpenAI's custom-patched Electron fork used for the official macOS/Windows builds. The stock open-source Electron this project ships on Linux never has it, so the call throws unconditionally and the bootstrapcatchblock aborts startup (the actualErroris only sent to Sentry, not logged, which is why this was hard to see from the launcher log — it just showedDesktop bootstrap failed to start the main app phase=bootstrap-import-mainand a generic "failed to start" dialog).Fix
scripts/patches/bootstrap.js: addedapplyLinuxOwlFeatureGuardPatch/patchLinuxOwlFeatureGuard, which locates the Owl feature-binding lookup by content (it lives in a content-hashed chunk file pulled in by the main bundle, not a fixed path) and wraps it so a missing binding degrades to{isOwlFeatureEnabled: () => false}instead of throwing.scripts/patches/core/all-linux/extracted-app/owl-feature-guard/patch.js: registers it as a normalextracted-app-phase core patch (same shape as the existinglinux-multi-instance-bootstrap-lockpatch), so it's picked up automatically by the existing patch engine — no other wiring needed.Test plan
make build-app DMG=./Codex.dmg— patch applies cleanly (changed: true), confirmed the guarded fallback landed in the packedapp.asar.codex-app/start.shdirectly against the patched build — it now boots past bootstrap, loads the webview UI, and connects to the app-server backend (thread/listsucceeds), instead of crashing every time as before.make deband installed over an existing broken install withapt-get install; app now opens normally from the desktop launcher.🤖 Generated with Claude Code