fix(desktop): avoid recursive cpSync in stage-native-deps (Windows build crash) - #61829
Closed
danilofalcao wants to merge 1 commit into
Closed
danilofalcao wants to merge 1 commit into
danilofalcao wants to merge 1 commit into
Conversation
…ild crash)
Node 22.x's native recursive cpSync (cpSyncCopyDir) is unreliable on
Windows. Copying a directory tree throws `EIO: "Access is denied."` on the
`\\?\`-prefixed destination — even for a plain directory of .js files — and
hard-crashes the whole process (exit 3221226505 / 0xC0000409 /
STATUS_STACK_BUFFER_OVERRUN) while copying node-pty's conpty payload
(OpenConsole.exe + conpty.dll). Per-file, non-recursive cpSync works fine.
The crash is silent (no stack trace, since it's a native fault, not a JS
throw) and killed `npm run pack` at the stage-native-deps step. The desktop
launcher misreports this as a blocked Electron download and retries via a
mirror, but the build never actually reaches the electron-builder step.
Route the two `cpSync(dir, { recursive: true })` calls through a manual
walk (copyDirRecursive) that copies each file individually — the same
pattern copyGlobByExt already uses reliably. Add regression tests covering
the copy behavior and guarding against reintroducing recursive cpSync.
danilofalcao
force-pushed
the
fix/desktop-stage-native-deps-windows-cpsync
branch
from
July 10, 2026 03:11
755e551 to
f392929
Compare
3 tasks
This was referenced Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes a hard crash that makes the desktop app impossible to build/package on Windows.
npm run pack(invoked byhermes desktop) dies silently at thestage-native-depsstep with exit code3221226505(0xC0000409/STATUS_STACK_BUFFER_OVERRUN):Root cause: Node 22.x's native recursive
cpSync(cpSyncCopyDir) is unreliable on Windows.cpSync(src, dest, { recursive: true })throwsEIO: "Access is denied."on the\\?\-prefixed destination — reproducible even for a plain directory of.jsfiles — and hard-crashes the whole process (0xC0000409) when copying node-pty'sconptypayload (OpenConsole.exe+conpty.dll). Per-file, non-recursivecpSyncworks every time.Because the fault is native (not a JS exception), there's no stack trace and it can't be caught/retried — the process just vanishes. The desktop launcher then misreports this as a blocked Electron download and retries via a mirror, but the build never actually reaches the
electron-builderstep, so the retry can't help.The fix routes the two recursive-
cpSyncdirectory copies instage-native-deps.mjsthrough a small manual walk (copyDirRecursive) that copies files individually — the exact pattern the neighbouringcopyGlobByExtalready uses reliably. No behavior change on macOS/Linux (they were fine; this just uses a codepath that also works on Windows).Related Issue
No linked issue — happy to open one if you'd prefer to track it. Fixes #
Type of Change
Changes Made
apps/desktop/scripts/stage-native-deps.mjscopyDirRecursive(srcDir, destDir)— walks a directory withreaddirSyncand copies each file with a non-recursivecpSync(recursing into subdirs itself), with a comment explaining why recursivecpSyncis avoided.cpSync(dir, { recursive: true })calls (copyBuildReleaseforbuild/Release/*subdirs, and theprebuilds/<target>/conptycopy) withcopyDirRecursive.apps/desktop/scripts/stage-native-deps.test.mjs(new)copyDirRecursivereproduces a nested tree (incl. aconpty/subdir with binary blobs) with byte-exact copies.stage-native-deps.mjsnever callscpSyncwith{ recursive: true }(the crashing API).How to Test
Reproduction (Windows 11, Node 22.x, from
apps/desktop):main:npm run build→ crashes atstage-native-depswithnpm error code 3221226505, no stack trace.npm run build→ exits0;npm run pack→ exits0and producesrelease/win-unpacked/Hermes.exewith the node-pty conpty binaries staged underresources/app.asar.unpacked/dist/node_modules/node-pty/.Unit tests:
Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass — N/A, this is a desktop build-script (Node) change; rannode --test scripts/stage-native-deps.test.mjs(3/3 pass) insteadnpm run packnow succeedsDocumentation & Housekeeping
docs/, docstrings) — code comment added explaining the Windows cpSync pitfall; no user-facing docs affectedcli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Before (on
main):After (this PR):