Fix the two reasons the packaged app would not open - #5
Merged
Conversation
v0.0.1 aborted before drawing a window. The first cause was hiding the second.
CFBundleName was overridden to "RoleModel Studio". Electron resolves its helper
apps from CFBundleName, and electron-builder names them after `productName`, so
they ship as "Openscreen Helper.app" — leaving Electron looking for "RoleModel
Studio Helper.app", finding nothing, and aborting:
FATAL:electron_main_delegate_mac.mm:65] Unable to find helper app
Our own cask comments describe this failure, in the note explaining why there is
no `binary` stanza. It was reached a different way here, and the diagnosis missed
it for a while because the process exited 133 with that single line.
Nothing is lost by leaving CFBundleName alone. The menu bar reads "RoleModel
Studio" because main.ts calls app.setName(PRODUCT_NAME) at module scope, and
Finder, the Dock, the About panel and every permission prompt read
CFBundleDisplayName, which stays.
With that fixed the app got further and threw:
The 'screen' module can't be used before the app 'ready' event
`app.on("activate")` called showMainWindow with no readiness guard, and activate
can arrive before whenReady — exactly what the open-file handler twelve lines
above already guards against. The window it builds measures the primary display,
so the throw takes the main process down. Ignoring an early activate costs
nothing: whenReady builds the window anyway, and macOS re-sends activate on a dock
click.
Worth recording how this was mis-diagnosed twice. The first theory was hardened
runtime, from `flags=0x10002(adhoc,runtime)` on the release against
`0x20002(adhoc,linker-signed)` on the working dev build; re-signing without it
changed nothing. The second was a silent single-instance quit, from an exit code
of 0 with no output — which was this shell exporting ELECTRON_RUN_AS_NODE=1, so
the binary was running as node and reading empty stdin. The real error only
appeared with that unset.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.0.1 aborted before drawing a window. The first cause was hiding the second.
1. CFBundleName broke helper resolution
CFBundleNamewas overridden to"RoleModel Studio". Electron resolves its helper apps from CFBundleName, and electron-builder names them afterproductName— so they ship asOpenscreen Helper.appwhile Electron went looking forRoleModel Studio Helper.app:Exit 133 (SIGTRAP), one line of output, no crash report. Our own cask comments describe this exact failure in the note explaining why there's no
binarystanza — reached a different way here.Nothing is lost by leaving
CFBundleNamealone:app.setName(PRODUCT_NAME)at module scope in main.tsCFBundleDisplayName, unchanged2.
activatefires before readyWith that fixed the app got further and threw:
app.on("activate")calledshowMainWindow()with no readiness guard — andactivatecan arrive beforewhenReady, which is exactly what theopen-filehandler twelve lines above already guards against:The window it builds measures the primary display, so the throw takes the main process down. Ignoring an early activate costs nothing:
whenReadybuilds the window anyway, and macOS re-sends activate on a dock click.How this was mis-diagnosed twice
Worth recording, because both wrong turns were plausible:
flags=0x10002(adhoc,runtime); the working dev build is0x20002(adhoc,linker-signed). Re-signing without hardened runtime changed nothing — thecodesign_utilerror was incidental noise at ERROR level, not the fatal.requestSingleInstanceLock()returning false. It was this shell exportingELECTRON_RUN_AS_NODE=1— the binary was running as node and reading empty stdin. The real error only appeared with that unset.Verified locally: patching
CFBundleNamein the installed bundle and re-signing cleared the FATAL and produced thescreenerror, which is how the second bug was found.🤖 Generated with Claude Code