scripts/release/verify-mac.ts claims to check that the packaged native module matches the
target architecture. It probes the wrong module and cannot fail:
const sqliteNode = join(
appDir, 'Contents', 'Resources', 'app.asar.unpacked',
'node_modules', 'sqlite3', 'build', 'Release', 'node_sqlite3.node'
);
...
} else {
warn(`sqlite3 native module not found at ${sqliteNode}`);
}
The app uses better-sqlite3, whose packaged binary is
app.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node. sqlite3 is
listed in the root pnpm.onlyBuiltDependencies but is not what the main process loads, so the
path never exists, the existsSync branch is never taken, and the arch assertion is replaced
by a warn() on every single release. The Electron binary's own arch is checked, so the
script is not useless — but its native-module half has never run.
Why it matters
This is the guard that should have caught the v1.2.8 incident (see the "native-module rebuild"
section of FORK.md), where the packaged better-sqlite3 was compiled for the runner's system
Node and the app could not boot. It passed. #80 added
scripts/release/verify-native-abi.ts, which loads the packaged modules in the packaged
Electron and covers the ABI question properly — but the architecture question this script was
written to answer is still unchecked for native modules, and a cross-arch mismatch would look
identical to a clean run.
What to do
Point the probe at better-sqlite3 (ideally at every entry of NATIVE_MODULES from
scripts/release/lib/config.ts, so the list stays in one place), and decide deliberately
whether a missing module should warn or fail. Given verify-native-abi.ts now hard-fails
when the module is absent, fail is defensible here too — a release whose native modules are
missing is not a release.
verify-linux.ts does not have this problem — it globs for any .node under the release
directory and hard-fails when it finds none, so no hardcoded module name can go stale there.
Only the macOS script names a module.
Note this is an upstream-owned file, so keep the diff minimal and expect it to be a rebase
touch point — or consider whether the check belongs in the fork-side verify script instead.
scripts/release/verify-mac.tsclaims to check that the packaged native module matches thetarget architecture. It probes the wrong module and cannot fail:
The app uses
better-sqlite3, whose packaged binary isapp.asar.unpacked/node_modules/better-sqlite3/build/Release/better_sqlite3.node.sqlite3islisted in the root
pnpm.onlyBuiltDependenciesbut is not what the main process loads, so thepath never exists, the
existsSyncbranch is never taken, and the arch assertion is replacedby a
warn()on every single release. The Electron binary's own arch is checked, so thescript is not useless — but its native-module half has never run.
Why it matters
This is the guard that should have caught the v1.2.8 incident (see the "native-module rebuild"
section of
FORK.md), where the packagedbetter-sqlite3was compiled for the runner's systemNode and the app could not boot. It passed. #80 added
scripts/release/verify-native-abi.ts, which loads the packaged modules in the packagedElectron and covers the ABI question properly — but the architecture question this script was
written to answer is still unchecked for native modules, and a cross-arch mismatch would look
identical to a clean run.
What to do
Point the probe at
better-sqlite3(ideally at every entry ofNATIVE_MODULESfromscripts/release/lib/config.ts, so the list stays in one place), and decide deliberatelywhether a missing module should
warnorfail. Givenverify-native-abi.tsnow hard-failswhen the module is absent,
failis defensible here too — a release whose native modules aremissing is not a release.
verify-linux.tsdoes not have this problem — it globs for any.nodeunder the releasedirectory and hard-fails when it finds none, so no hardcoded module name can go stale there.
Only the macOS script names a module.
Note this is an upstream-owned file, so keep the diff minimal and expect it to be a rebase
touch point — or consider whether the check belongs in the fork-side verify script instead.