Summary
- A Node.js harness reproduced the native Edge crash without Playwright, Puppeteer, Selenium, or third-party packages.
- Edge, profile state, input files, CDP commands, and shutdown procedure were held constant while the transport changed.
- Raw CDP over pipe crashed on the second or third browser process after profile reuse.
- Raw CDP over port completed 8 / 8 runs, with matching file sizes and SHA-256 hashes.
Why remove Playwright
The earlier tests had excluded the original profile, headless mode, and download.save_as() as required causes. Playwright’s launch behavior and command ordering still remained in the system.
Reproducing the same native termination without Playwright would establish that the Python application and Playwright’s higher-level Download API were not necessary conditions.
The reduced harness uses only:
- Node.js standard modules;
- Microsoft Edge;
- a dedicated test profile;
- a local HTTP server;
- raw CDP JSON messages.
Dependency-free harness
The reproduction performs the following steps:
- Starts an HTTP server on localhost.
- Generates a deterministic 5 MiB file and an HTML page containing five download links.
- Creates a new Edge profile in a test-only user-data directory.
- Opens the page and configures download behavior through CDP.
- Activates each link and waits for the file.
- Validates file size and SHA-256.
- Closes Edge with
Browser.close. - Starts the next Edge process with the same profile.
The test does not depend on an external website, a personal Edge profile, extensions, or authentication state.
Transport comparison
CDP commands can reach Edge through two transport paths:
| Transport | Launch option | Connection |
|---|---|---|
| Pipe | --remote-debugging-pipe |
Dedicated parent-child process pipes |
| Port | --remote-debugging-port |
Local HTTP and WebSocket endpoint |
Both paths carry CDP messages. This makes the transport a useful independent variable when the remaining conditions are fixed.
Pipe result
The pipe test used the following form:
node repro.mjs --transport pipe --iterations 5 --download-behavior allow
The first Edge process and its downloads completed. Edge then terminated during the second process, or during the third process in some attempts.
run=1 transport=pipe result=ok
run=2 transport=pipe result=failed
exit_code=3221225477 (0xC0000005)
Some failed runs left a fully written 5 MiB .crdownload file that had not been renamed to the final filename. This is consistent with a failure near download completion, but it does not identify the exact internal operation.
Port result
Only the transport argument changed:
node repro.mjs --transport port --iterations 8 --download-behavior allow
All eight processes completed successfully.
run=1 transport=port result=ok
run=2 transport=port result=ok
run=3 transport=port result=ok
run=4 transport=port result=ok
run=5 transport=port result=ok
run=6 transport=port result=ok
run=7 transport=port result=ok
run=8 transport=port result=ok
Every downloaded file had the expected 5 MiB size and SHA-256 hash.
Controlled variables
The comparison held these inputs constant:
- Edge 152.0.4191.53 executable;
- user-data directory;
- generated 5 MiB HTTP response;
- HTML and link activation;
Browser.setDownloadBehaviorcommand;- target creation and attachment sequence;
Browser.closeshutdown procedure.
The independent variable was:
A: --remote-debugging-pipe
B: --remote-debugging-port=<temporary local port>
Cross-checks
| Configuration | Observed result |
|---|---|
| Edge 152 + raw CDP pipe | Native crash on the second or third process |
| Edge 152 + raw CDP port | 8 / 8 successful |
| Edge 152 launched over port, Playwright attached | 2 / 2 successful |
| Playwright-bundled Chromium 151 + persistent pipe | 25 / 25 successful |
| New Edge profile, first browser process only | 5 / 5 successful |
Chromium 151 and Edge 152 are not identical versions, so this comparison alone cannot establish an Edge 152 regression. It does show that the failure was not universal across the tested Chromium-based browser paths.
Narrowed failure boundary
The reproduction was narrowed to the following observed combination:
Microsoft Edge 152
same profile reused by another Edge process
download performed under CDP control
remote-debugging-pipe transport
native process crash
Changing to a port transport, changing to the bundled Chromium build, or limiting the test to the first Edge process did not reproduce the crash in the recorded runs.
Eight successful port runs are a useful control, not proof that the port path is safe across every environment. The precise claim is that the crash did not reproduce over port in the tested environment and run count while other relevant conditions were held fixed.
Next test
The final step compares Crashpad dumps from headed, headless, and raw CDP runs to determine whether those paths converge on the same native failure signature.