Microsoft Edge 152
Native Crash Investigation
A Playwright-observed download failure was reduced to a native Edge crash involving a reused user-data directory and CDP pipe transport. A dependency-free Node.js harness reproduced the failure with raw CDP commands, allowing the transport path and other variables to be compared independently.
Context
The investigation began with Playwright reporting TargetClosedError while handling a download. Process-level observations showed that Edge had already terminated, so the application error was treated as a downstream symptom rather than the cause.
Failure
On Microsoft Edge Stable 152, the failure appeared after reusing the same profile across browser processes while performing downloads under CDP control through --remote-debugging-pipe. The Edge process exited with a native read-access violation inside msedge.dll.
Reduction
The original application was reduced in stages. Existing profile state was removed, headed and headless modes were compared, and download.save_as() was eliminated. Playwright was then removed entirely.
The final reproduction uses only Node.js standard modules to start a local server, launch Edge, exchange raw CDP messages, download deterministic files, validate their size and SHA-256, close the browser, and repeat with the same profile.
Experiment Matrix
| Configuration | Observed result |
|---|---|
| Edge + raw CDP pipe | Native crash after profile reuse |
| Edge + raw CDP port | 8 / 8 successful |
| Edge + Playwright over CDP port | Successful |
| Playwright-bundled Chromium + persistent pipe | 25 / 25 successful |
| Edge headed / headless | Both reproduce |
| Edge without download.save_as() | Still reproduces |
Results describe the tested environment and run counts; they do not establish safety across all Edge versions or systems.
Crash Signature
- Exception
0xC0000005- Access
- Read
- Module
msedge.dll 152.0.4191.53- Module offset
0x9D5C88B- Invalid address
- Near-null,
0x18–0x21
Crashpad dumps collected from Playwright headless, Playwright headed, and raw CDP pipe runs converged on the same module offset. This supports a common native failure path, but does not identify the internal source line or prove a security impact.
Findings
- The original profile alone did not explain the crash; newly created profiles reproduced after reuse.
- Headless mode was not required.
download.save_as()and Playwright's Download API were not required.- Playwright itself was not required; raw CDP reproduced the native failure.
- Changing only the CDP transport from pipe to port changed the observed result in the controlled comparison.
Mitigation
The most reliable observed mitigation was to launch Edge independently with --remote-debugging-port and attach with Playwright's connect_over_cdp(). The debugging endpoint should remain bound to localhost and a dedicated automation profile should be used.
This is a transport-level workaround, not a root-cause fix.