Skip to content

Fix the two reasons the packaged app would not open - #5

Merged
dallasbpeters merged 1 commit into
mainfrom
rolemodel/fix-launch
Aug 24, 2026
Merged

Fix the two reasons the packaged app would not open#5
dallasbpeters merged 1 commit into
mainfrom
rolemodel/fix-launch

Conversation

@dallasbpeters

Copy link
Copy Markdown
Member

v0.0.1 aborted before drawing a window. The first cause was hiding the second.

1. CFBundleName broke helper resolution

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 while Electron went looking for RoleModel Studio Helper.app:

FATAL:electron/shell/app/electron_main_delegate_mac.mm:65] Unable to find 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 binary stanza — reached a different way here.

Nothing is lost by leaving CFBundleName alone:

what a person sees where it comes from
menu bar app.setName(PRODUCT_NAME) at module scope in main.ts
Finder, Dock, About, permission prompts CFBundleDisplayName, unchanged

2. activate fires before ready

With that fixed the app got further and threw:

The 'screen' module can't be used before the app 'ready' event
    at createHudOverlayWindow → createWindow → showMainWindow

app.on("activate") called showMainWindow() with no readiness guard — and activate can arrive before whenReady, which is exactly what the open-file handler twelve lines above already guards against:

if (app.isReady()) openProjectPath(filePath);
else pendingOpenPath = filePath;

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.

How this was mis-diagnosed twice

Worth recording, because both wrong turns were plausible:

  1. Hardened runtime. The release was flags=0x10002(adhoc,runtime); the working dev build is 0x20002(adhoc,linker-signed). Re-signing without hardened runtime changed nothing — the codesign_util error was incidental noise at ERROR level, not the fatal.
  2. A silent single-instance quit. Direct runs exited 0 with no output, which looked like requestSingleInstanceLock() returning false. It was this shell exporting ELECTRON_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 CFBundleName in the installed bundle and re-signing cleared the FATAL and produced the screen error, which is how the second bug was found.

🤖 Generated with Claude Code

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>
@dallasbpeters
dallasbpeters merged commit 78c7e35 into main Aug 24, 2026
13 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant