Repository navigation
fix(electron): strip stale native modules from NEXT_DIST_DIR, not hardcoded .next - #8794
Merged
diegosouzapw merged 1 commit intoJul 28, 2026
Conversation
removeNativeModules() was called with a hardcoded ".next" path while the actual
distDir is NEXT_DIST_DIR (".build/next" by default). Because the function
early-returns when the directory does not exist, the cleanup silently no-opped
and the plain-Node-ABI better-sqlite3 copy produced by `next build` survived
into the packaged app.
At runtime the standalone server runs under ELECTRON_RUN_AS_NODE, so it needs
the Electron ABI (148 for electron 43). Loading the ABI-137 copy fails with
ERR_DLOPEN_FAILED, the app falls back to the sql.js WASM driver, the connection
is closed and retried in a loop, WASM memory is never reclaimed and the process
OOMs -> HTTP 500 on every route.
Also adds assertNoStaleHashedNatives() so a wrong baseDir fails the build
instead of silently shipping a broken installer. This has regressed at least
twice (diegosouzapw#1497 with ABI 127 vs 145, diegosouzapw#7082/diegosouzapw#7681 with 137 vs 148).
Refs diegosouzapw#7082, diegosouzapw#7681, diegosouzapw#1497, diegosouzapw#8792. Supersedes the abandoned diegosouzapw#7123.
Merged
HouMinXi
pushed a commit
to HouMinXi/OmniRoute
that referenced
this pull request
Aug 2, 2026
…iegosouzapw#8794) removeNativeModules() was called with a hardcoded ".next" path while the actual distDir is NEXT_DIST_DIR (".build/next" by default). Because the function early-returns when the directory does not exist, the cleanup silently no-opped and the plain-Node-ABI better-sqlite3 copy produced by `next build` survived into the packaged app. At runtime the standalone server runs under ELECTRON_RUN_AS_NODE, so it needs the Electron ABI (148 for electron 43). Loading the ABI-137 copy fails with ERR_DLOPEN_FAILED, the app falls back to the sql.js WASM driver, the connection is closed and retried in a loop, WASM memory is never reclaimed and the process OOMs -> HTTP 500 on every route. Also adds assertNoStaleHashedNatives() so a wrong baseDir fails the build instead of silently shipping a broken installer. This has regressed at least twice (diegosouzapw#1497 with ABI 127 vs 145, diegosouzapw#7082/diegosouzapw#7681 with 137 vs 148). Refs diegosouzapw#7082, diegosouzapw#7681, diegosouzapw#1497, diegosouzapw#8792. Supersedes the abandoned diegosouzapw#7123.
This was referenced Aug 14, 2026
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…iegosouzapw#8794) removeNativeModules() was called with a hardcoded ".next" path while the actual distDir is NEXT_DIST_DIR (".build/next" by default). Because the function early-returns when the directory does not exist, the cleanup silently no-opped and the plain-Node-ABI better-sqlite3 copy produced by `next build` survived into the packaged app. At runtime the standalone server runs under ELECTRON_RUN_AS_NODE, so it needs the Electron ABI (148 for electron 43). Loading the ABI-137 copy fails with ERR_DLOPEN_FAILED, the app falls back to the sql.js WASM driver, the connection is closed and retried in a loop, WASM memory is never reclaimed and the process OOMs -> HTTP 500 on every route. Also adds assertNoStaleHashedNatives() so a wrong baseDir fails the build instead of silently shipping a broken installer. This has regressed at least twice (diegosouzapw#1497 with ABI 127 vs 145, diegosouzapw#7082/diegosouzapw#7681 with 137 vs 148). Refs diegosouzapw#7082, diegosouzapw#7681, diegosouzapw#1497, diegosouzapw#8792. Supersedes the abandoned diegosouzapw#7123.
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.
Fixes the packaging defect behind the recurring "Internal Server Error on every route" reports on the Electron desktop build.
Reported with full forensics in #8792. Supersedes the abandoned #7123 (closed unmerged,
CONFLICTING).The bug
prepare-electron-standalone.mjsstrips stale native module copies after rebuildingbetter-sqlite3for the Electron ABI, but the cleanup call hardcodes".next":The real
distDiris.build/next. SinceremoveNativeModules()early-returns when the directory does not exist, the cleanup silently no-ops and the plain-Node-ABI copy produced bynext buildships inside the installer.The intent was already documented in the surrounding comment — only the path was wrong:
Runtime impact
The standalone server runs under
ELECTRON_RUN_AS_NODE, so it needs the Electron ABI (148 for electron 43), but gets the Node one (137):Verified on a clean install of v3.8.48 (Windows 11, Electron 43.1.0). Auditing every
.nodein the package byrequire()-ing it inside the app's own Electron runtime showed exactly one mismatch:Overwriting the bundled copy with the correctly-built one that already ships in the same package restores the app immediately: HTTP 200 within ~2s, zero OOM entries, real
/v1/messagescompletions succeed.Changes
removeNativeModules(... NEXT_DIST_DIR ...)instead of the hardcoded".next".assertNoStaleHashedNatives()— throws if any hashed native copies survive the cleanup.The second change is the reason this PR is not a one-liner. The failure mode here is a silent no-op: a wrong
baseDirproduces a green build and a broken installer, and the mismatch only surfaces on a user machine after their DB grows enough thatsql.jscan no longer load it. That is why this has regressed at least twice:With the assertion, a wrong path fails the build instead of shipping.
Notes
assertNoStaleHashedNatives()reusesexistsSync/readdirSync, already imported in this file.node --check.Refs #7082, #7681, #1497, #8792.