[GH-ISSUE #1589] [Bug] Windows Electron cleanup signals an unverified PID #536

Closed
opened 2026-10-15 18:25:58 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @Adolanium on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1589

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

On Windows, capture_electron_scenario runs taskkill.exe /pid <leader> /t /f on the PID recorded at Electron launch, then returns cleanup_failed because process lineage is unavailable. The Windows process-table host returns no rows, so lineage cannot be verified even while the leader is still alive. A successful capture is retained only as details.partial_observation.

#288 covers Ghidra Job Object ownership. It does not cover this Electron path. Production Ghidra cleanup uses the Job Object callback when that callback exists.

Reproduction

  1. Run REA on Windows with the Electron scenario provider enabled.
  2. Call capture_electron_scenario for a local Electron application.
  3. Observe cleanup. cleanupElectronProcesses calls cleanupWindowsProcessTree before checking lineage.status. observeOwnedProcessLineage uses a host whose listProcesses returns [] on win32, so the status is unavailable and the reason is owned launcher is not live.
  4. The operation fails with cleanup_failed. The taskkill has already been issued.

A focused regression injects platform: "win32" and a terminate function. Unavailable lineage must not call terminate.

Expected behavior

Cleanup uncertainty does not authorize signaling an unrelated process (docs/electron-observation.md). A PID and path do not establish ownership after exit or reuse. Windows should return the unverified-cleanup failure without calling taskkill unless lineage has been verified. Verified lineage may still terminate the leader and its descendants.

An unverified Windows capture may still fail closed. This report does not ask for that lane to return success.

Impact and scope

Windows active Electron capture can kill whatever process now owns the recorded PID, including after application.close() reaps the leader and the PID is reused. Descendants are killed through taskkill /t as part of that same call. POSIX cleanup is unchanged and still revalidates the run token before signaling. Passive Electron CDP observation is a different operation.

REA version

6.3.0, revision 02ef2b1c41e80364b6482e4586ae40e575c6d5a5

Runtime and platform

Node 22 or 24 on Windows x64. The signal happens only on win32.

Target and artifact context

Local Electron application launched by capture_electron_scenario. Not applicable to a binary target.

Interface

CLI

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

cleanup_failed, with reason owned Electron lineage was unavailable; helper cleanup was not proven, after taskkill.exe /pid <leader> /t /f. Collected observations stay on details.partial_observation with application cleanup unverified.

Typed outcome or recovery expected

cleanup_failed with the same reason when lineage is unavailable, and no taskkill. cleaned: true only after verified lineage and successful termination of the leader and descendants.

Analysis or suspected cause

Source-derived. cleanupElectronProcesses in src/browser/PlaywrightElectronActiveProvider.ts called cleanupWindowsProcessTree before the lineage check. createSystemProcessOwnershipHost returns [] from listProcesses on win32, so the verified branch was unreachable and the signal still ran. cleanupWindowsProcessTree checks only that the PID is a positive safe integer.

Additional context

Fix is in https://github.com/morluto/rea/pull/1588. Regression: src/browser/PlaywrightElectronActiveProvider.test.ts.

Originally created by @Adolanium on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1589 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior On Windows, `capture_electron_scenario` runs `taskkill.exe /pid <leader> /t /f` on the PID recorded at Electron launch, then returns `cleanup_failed` because process lineage is unavailable. The Windows process-table host returns no rows, so lineage cannot be verified even while the leader is still alive. A successful capture is retained only as `details.partial_observation`. `#288` covers Ghidra Job Object ownership. It does not cover this Electron path. Production Ghidra cleanup uses the Job Object callback when that callback exists. ### Reproduction 1. Run REA on Windows with the Electron scenario provider enabled. 2. Call `capture_electron_scenario` for a local Electron application. 3. Observe cleanup. `cleanupElectronProcesses` calls `cleanupWindowsProcessTree` before checking `lineage.status`. `observeOwnedProcessLineage` uses a host whose `listProcesses` returns `[]` on `win32`, so the status is `unavailable` and the reason is `owned launcher is not live`. 4. The operation fails with `cleanup_failed`. The `taskkill` has already been issued. A focused regression injects `platform: "win32"` and a terminate function. Unavailable lineage must not call terminate. ### Expected behavior Cleanup uncertainty does not authorize signaling an unrelated process (`docs/electron-observation.md`). A PID and path do not establish ownership after exit or reuse. Windows should return the unverified-cleanup failure without calling `taskkill` unless lineage has been verified. Verified lineage may still terminate the leader and its descendants. An unverified Windows capture may still fail closed. This report does not ask for that lane to return success. ### Impact and scope Windows active Electron capture can kill whatever process now owns the recorded PID, including after `application.close()` reaps the leader and the PID is reused. Descendants are killed through `taskkill /t` as part of that same call. POSIX cleanup is unchanged and still revalidates the run token before signaling. Passive Electron CDP observation is a different operation. ### REA version 6.3.0, revision `02ef2b1c41e80364b6482e4586ae40e575c6d5a5` ### Runtime and platform Node 22 or 24 on Windows x64. The signal happens only on `win32`. ### Target and artifact context Local Electron application launched by `capture_electron_scenario`. Not applicable to a binary target. ### Interface CLI ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence `cleanup_failed`, with reason `owned Electron lineage was unavailable; helper cleanup was not proven`, after `taskkill.exe /pid <leader> /t /f`. Collected observations stay on `details.partial_observation` with application cleanup `unverified`. ### Typed outcome or recovery expected `cleanup_failed` with the same reason when lineage is unavailable, and no `taskkill`. `cleaned: true` only after verified lineage and successful termination of the leader and descendants. ### Analysis or suspected cause Source-derived. `cleanupElectronProcesses` in `src/browser/PlaywrightElectronActiveProvider.ts` called `cleanupWindowsProcessTree` before the lineage check. `createSystemProcessOwnershipHost` returns `[]` from `listProcesses` on `win32`, so the verified branch was unreachable and the signal still ran. `cleanupWindowsProcessTree` checks only that the PID is a positive safe integer. ### Additional context Fix is in https://github.com/morluto/rea/pull/1588. Regression: `src/browser/PlaywrightElectronActiveProvider.test.ts`.
bsakaguchi 2026-10-15 18:25:58 +00:00
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#536
No description provided.