-
Notifications
You must be signed in to change notification settings - Fork 683
fix: detect and rebuild better-sqlite3 on Node.js ABI mismatch #1373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -226,7 +226,35 @@ function sqliteBindingsExist() { | |||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (sqliteBindingsExist()) { | ||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * Check whether better-sqlite3 can actually be loaded by the current | ||||||||||||||||||||||||||||||
| * Node.js runtime. A binding file may exist on disk but still fail | ||||||||||||||||||||||||||||||
| * with NODE_MODULE_VERSION mismatch after a Node.js or plugin update. | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| function sqliteLoadsSuccessfully() { | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| require(path.join(sqliteModulePath, "lib", "index.js")); | ||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||
| if (e && e.message && e.message.includes("NODE_MODULE_VERSION")) { | ||||||||||||||||||||||||||||||
| warn("ABI version mismatch — native module was built for a different Node.js version."); | ||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| // For any other load error fall through to the rebuild path as well. | ||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let needsRebuild = false; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (!sqliteBindingsExist()) { | ||||||||||||||||||||||||||||||
| warn("better-sqlite3 native bindings not found in plugin dir."); | ||||||||||||||||||||||||||||||
| log(`Searched in: ${DIM}${sqliteModulePath}/build/${RESET}`); | ||||||||||||||||||||||||||||||
| needsRebuild = true; | ||||||||||||||||||||||||||||||
| } else if (!sqliteLoadsSuccessfully()) { | ||||||||||||||||||||||||||||||
| log("Native binding file exists but cannot be loaded by current Node.js."); | ||||||||||||||||||||||||||||||
| needsRebuild = true; | ||||||||||||||||||||||||||||||
|
Comment on lines
+248
to
+256
|
||||||||||||||||||||||||||||||
| let needsRebuild = false; | |
| if (!sqliteBindingsExist()) { | |
| warn("better-sqlite3 native bindings not found in plugin dir."); | |
| log(`Searched in: ${DIM}${sqliteModulePath}/build/${RESET}`); | |
| needsRebuild = true; | |
| } else if (!sqliteLoadsSuccessfully()) { | |
| log("Native binding file exists but cannot be loaded by current Node.js."); | |
| needsRebuild = true; | |
| if (!sqliteBindingsExist()) { | |
| warn("better-sqlite3 native bindings not found in plugin dir."); | |
| log(`Searched in: ${DIM}${sqliteModulePath}/build/${RESET}`); | |
| } else if (!sqliteLoadsSuccessfully()) { | |
| log("Native binding file exists but cannot be loaded by current Node.js."); |
Copilot
AI
Mar 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the script distinguishes “binding exists” vs “binding loads”, the post-rebuild success path should also validate loadability (not just file existence). Otherwise npm rebuild could succeed and produce a .node file that still fails to load (ABI mismatch persists, wrong prebuild selected, missing runtime dependency), and the script would report success anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sqliteLoadsSuccessfully()intentionally suppresses all non-ABI load errors. That makes failures like missing DLLs / wrong arch / missing dependency harder to diagnose. Consider logging (at least a truncated)e.messagewhen the error is not aNODE_MODULE_VERSIONmismatch so users have actionable context before the rebuild attempt.