[GH-ISSUE #2974] capture_electron_scenario: packaged Windows Electron apps fail at launch (env allowlist breaks app boot; Playwright attach times out; -r hook never installs) #1044

Open
opened 2026-10-15 18:30:36 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @ruined83 on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2974

capture_electron_scenario: packaged Windows Electron apps fail at launch (env allowlist breaks app boot; Playwright attach times out; -r hook never installs)

Environment

  • rea-agents 6.4.0 (npm global, commit a56f7bb6), Node 26.10.0, Windows 10 x64
  • Target: packaged Electron app Notion 7.21.0 (Electron 41.3.0, win32 x64), installed at %LOCALAPPDATA%\Programs\Notion
  • Playwright: playwright-core bundled with rea-agents 6.4.0

capture_electron_scenario cannot produce any evidence for this target. Three independent blockers, each isolated with controlled repros. Even one fixed alone does not unblock the flow.

Blocker 1 — safeElectronEnvironment allowlist strips Windows-critical variables, so the app never opens a window

dist/browser/PlaywrightElectronActiveProvider.js (6.4.0) launches the app with an env allowlist of only HOME, LANG, PATH, TMP, TMPDIR, USER, DISPLAY, WAYLAND_DISPLAY (+ REA_PROCESS_RUN_ID). On Windows this drops SYSTEMROOT, APPDATA, LOCALAPPDATA, USERPROFILE, TEMP, COMSPEC, … which consumer Electron apps need.

Repro (launching the app the same way the provider does — only PATH+TMP in the environment): the main process boots and logs

App starting with version 7.21.0 … system: 'win32 x64', electron: '41.3.0'
performance_event: 'app_launch_to_app_ready', duration_ms: ~217
ERROR:net\base\network_change_notifier_win.cc:195] WSALookupServiceBegin failed with: 10108
ERROR:media\audio\win\core_audio_util_win.cc:319] CoCreateInstance(MMDeviceEnumerator) failed: 8007007e
ServerLogger … type: 'unhandledRejection', error: { message: 'listen UNKNOWN: unknown error 127.0.0.1' }

and no BrowserWindow is ever created (40+ s observation: every Notion.exe PID has MainWindowHandle = 0). Playwright then hits the hardcoded STARTUP_TIMEOUT_MS = 60_000 (line 16) → TimeoutError: Timeout 60000ms exceeded in ElectronDispatcher._runCommand, and the CLI exits with no evidence.

Suggested fix: on win32 pass through at least SYSTEMROOT, TEMP, APPDATA, LOCALAPPDATA, USERPROFILE, COMSPEC, PATHEXT, PROGRAMDATA, ALLUSERSPROFILE, USERNAME, SYSTEMDRIVE, HOMEDRIVE, HOMEPATH (or the full parent environment with REA_PROCESS_RUN_ID appended).

Blocker 2 — even with a full environment, the Playwright attach handshake hangs for packaged apps

With the allowlist bypassed (env patched to full passthrough, then reverted), rea capture-electron-scenario still fails with the identical TimeoutError: Timeout 60000ms exceeded at ElectronDispatcher._runCommand.

Control experiment: the same app started manually with a full environment — including REA's exact argv (-r <electron-active-hook.cjs> <app.asar>, cwd = resources dir) — creates its main window in ~1 s. The only remaining delta is Playwright's own attach transport (--remote-debugging-pipe / node-inspector handshake). The app's --inspect=9229 listener is also refused at the socket level when passed explicitly (fuse-hardened Electron 41 build), so the node-inspector route is unavailable in this app class.

Suggested fix: fall back to --remote-debugging-port + CDP attach when the pipe handshake does not complete, or fail fast with a typed "target refuses inspector attach" error instead of a 60 s hang. For comparison, REA_GHIDRA_STARTUP_TIMEOUT_MS exists for the Ghidra provider; the Electron lane's 60 s ceiling has no input or environment knob.

Blocker 3 — -r <hook> <app.asar> argv is inert in packaged apps, so the IPC hook never installs

Repro: Notion.exe -r <marker-script.js> <app.asar> with a full environment — the marker is never created. Packaged Electron apps do not process Node CLI options, so scripts/electron-active-hook.cjs (which patches ipcMain.handle/on/once, webContents.send/postMessage, contextBridge, utilityProcess, and powers the IPC evidence families) never loads. Even with blockers 1–2 fixed, readApplicationState would record the hook snapshot as hook_error: true with zero events, and the capture's IPC evidence would be empty.

Suggested fix: document that active capture supports unpackaged electron-executable targets only, or add an injection vector that works for packaged apps.

Cleanup note

After each timeout the launched application is left running (observed orphaned Notion.exe process trees after every failed capture), so repeated retries accumulate live instances of the user's app.

Impact

Static analysis of packaged, minified Electron apps yields zero typed IPC/context-bridge findings (minification defeats lexical aliasing), and the active runtime lane intended to recover them is unavailable for the same app class. As a result the documented end-to-end flow (e.g. the Notion clipboard-bridge showcase) cannot be reproduced against a shipped Windows build of that app on 6.4.0. The passive CDP lane (list-electron-targets / inspect-electron-page via --remote-debugging-port) does work against this target and reconciles cleanly with the static graph — content digests even match byte-exactly (cdp_hash == static asset sha256) — but it records no IPC by design.

Happy to provide full logs and the repro scripts. Thanks for the toolkit — everything else in the pipeline (typed provider walls, honest unknown accounting, passive reconciliation) has been exemplary.

Originally created by @ruined83 on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2974 # `capture_electron_scenario`: packaged Windows Electron apps fail at launch (env allowlist breaks app boot; Playwright attach times out; `-r` hook never installs) ## Environment - rea-agents **6.4.0** (npm global, commit a56f7bb6), Node 26.10.0, Windows 10 x64 - Target: packaged Electron app **Notion 7.21.0** (Electron 41.3.0, win32 x64), installed at `%LOCALAPPDATA%\Programs\Notion` - Playwright: playwright-core bundled with rea-agents 6.4.0 `capture_electron_scenario` cannot produce any evidence for this target. Three independent blockers, each isolated with controlled repros. Even one fixed alone does not unblock the flow. ## Blocker 1 — `safeElectronEnvironment` allowlist strips Windows-critical variables, so the app never opens a window `dist/browser/PlaywrightElectronActiveProvider.js` (6.4.0) launches the app with an env allowlist of only `HOME, LANG, PATH, TMP, TMPDIR, USER, DISPLAY, WAYLAND_DISPLAY` (+ `REA_PROCESS_RUN_ID`). On Windows this drops `SYSTEMROOT`, `APPDATA`, `LOCALAPPDATA`, `USERPROFILE`, `TEMP`, `COMSPEC`, … which consumer Electron apps need. **Repro** (launching the app the same way the provider does — only `PATH`+`TMP` in the environment): the main process boots and logs ``` App starting with version 7.21.0 … system: 'win32 x64', electron: '41.3.0' performance_event: 'app_launch_to_app_ready', duration_ms: ~217 ERROR:net\base\network_change_notifier_win.cc:195] WSALookupServiceBegin failed with: 10108 ERROR:media\audio\win\core_audio_util_win.cc:319] CoCreateInstance(MMDeviceEnumerator) failed: 8007007e ServerLogger … type: 'unhandledRejection', error: { message: 'listen UNKNOWN: unknown error 127.0.0.1' } ``` and **no `BrowserWindow` is ever created** (40+ s observation: every `Notion.exe` PID has `MainWindowHandle = 0`). Playwright then hits the hardcoded `STARTUP_TIMEOUT_MS = 60_000` (line 16) → `TimeoutError: Timeout 60000ms exceeded` in `ElectronDispatcher._runCommand`, and the CLI exits with no evidence. **Suggested fix:** on win32 pass through at least `SYSTEMROOT, TEMP, APPDATA, LOCALAPPDATA, USERPROFILE, COMSPEC, PATHEXT, PROGRAMDATA, ALLUSERSPROFILE, USERNAME, SYSTEMDRIVE, HOMEDRIVE, HOMEPATH` (or the full parent environment with `REA_PROCESS_RUN_ID` appended). ## Blocker 2 — even with a full environment, the Playwright attach handshake hangs for packaged apps With the allowlist bypassed (env patched to full passthrough, then reverted), `rea capture-electron-scenario` still fails with the identical `TimeoutError: Timeout 60000ms exceeded` at `ElectronDispatcher._runCommand`. Control experiment: the **same app started manually with a full environment — including REA's exact argv** (`-r <electron-active-hook.cjs> <app.asar>`, `cwd` = resources dir) — creates its main window in ~1 s. The only remaining delta is Playwright's own attach transport (`--remote-debugging-pipe` / node-inspector handshake). The app's `--inspect=9229` listener is also refused at the socket level when passed explicitly (fuse-hardened Electron 41 build), so the node-inspector route is unavailable in this app class. **Suggested fix:** fall back to `--remote-debugging-port` + CDP attach when the pipe handshake does not complete, or fail fast with a typed "target refuses inspector attach" error instead of a 60 s hang. For comparison, `REA_GHIDRA_STARTUP_TIMEOUT_MS` exists for the Ghidra provider; the Electron lane's 60 s ceiling has no input or environment knob. ## Blocker 3 — `-r <hook> <app.asar>` argv is inert in packaged apps, so the IPC hook never installs Repro: `Notion.exe -r <marker-script.js> <app.asar>` with a full environment — the marker is never created. Packaged Electron apps do not process Node CLI options, so `scripts/electron-active-hook.cjs` (which patches `ipcMain.handle/on/once`, `webContents.send/postMessage`, `contextBridge`, `utilityProcess`, and powers the IPC evidence families) never loads. Even with blockers 1–2 fixed, `readApplicationState` would record the hook snapshot as `hook_error: true` with zero events, and the capture's IPC evidence would be empty. **Suggested fix:** document that active capture supports unpackaged `electron`-executable targets only, or add an injection vector that works for packaged apps. ## Cleanup note After each timeout the launched application is left running (observed orphaned `Notion.exe` process trees after every failed capture), so repeated retries accumulate live instances of the user's app. ## Impact Static analysis of packaged, minified Electron apps yields zero typed IPC/context-bridge findings (minification defeats lexical aliasing), and the active runtime lane intended to recover them is unavailable for the same app class. As a result the documented end-to-end flow (e.g. the Notion clipboard-bridge showcase) cannot be reproduced against a shipped Windows build of that app on 6.4.0. The passive CDP lane (`list-electron-targets` / `inspect-electron-page` via `--remote-debugging-port`) does work against this target and reconciles cleanly with the static graph — content digests even match byte-exactly (`cdp_hash` == static asset sha256) — but it records no IPC by design. Happy to provide full logs and the repro scripts. Thanks for the toolkit — everything else in the pipeline (typed provider walls, honest unknown accounting, passive reconciliation) has been exemplary.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1044
No description provided.