Skip to content

Commit e99e4ad

Browse files
gididafclaude
andcommitted
fix(installer): force native rebuild on every run + post-install smoke test
When `npm install --omit=dev` finds the lockfile already satisfied (the case on upgrade re-runs) it skips touching node_modules — including prebuilt native binaries. If the host's Node version has drifted since the original install, the cached better_sqlite3.node has the wrong ABI and the service crashloops with ERR_DLOPEN_FAILED on first openDb(). We hit this in the wild upgrading a v0.5.0 box (Node 23 at install time) to v0.6.0 (Node 20 now). The release tarball doesn't ship node_modules — the bad binary was preserved from the original install. Now: unconditionally `npm rebuild better-sqlite3` after the install step so the ABI matches the actual Node binary the service will use, and fail fast at install time with `node -e "require('better-sqlite3')"` instead of letting systemd find out the hard way. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4c31434 commit e99e4ad

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

install.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,24 @@ fi
275275
say "Installing production dependencies (this may take a minute)"
276276
(cd "$INSTALL_DIR" && npm install --omit=dev --no-audit --no-fund --silent) \
277277
|| die "npm install failed. If better-sqlite3 fails to build, install build tools: $PM install -y build-essential python3"
278+
279+
# Force-rebuild native deps against the current Node ABI. Necessary because
280+
# `npm install` is a no-op when the lockfile is already satisfied (e.g. on
281+
# upgrade re-runs) and so it doesn't rematerialize prebuilt binaries even
282+
# when Node has changed under it. Without this, a host whose Node version
283+
# shifted between installs (Node 23 → Node 20 was the v0.6.0 regression)
284+
# ends up with a NODE_MODULE_VERSION mismatch and the service crashloops on
285+
# `openDb()` with ERR_DLOPEN_FAILED.
286+
say "Rebuilding native modules for $(node --version)"
287+
(cd "$INSTALL_DIR" && npm rebuild better-sqlite3 --no-audit --no-fund --silent) \
288+
|| die "npm rebuild better-sqlite3 failed. Install build tools: $PM install -y build-essential python3"
289+
290+
# Fail fast at install time instead of letting systemd discover the ABI
291+
# mismatch via crashloop. Loads the native module under the same node
292+
# binary the service will use.
293+
if ! node -e "require('better-sqlite3')" 2>/dev/null; then
294+
die "better-sqlite3 still won't load under $(node --version). Try: cd $INSTALL_DIR && rm -rf node_modules && npm install --omit=dev"
295+
fi
278296
ok "Dependencies installed"
279297

280298
# --- Resolve runtime paths for the templated unit ---

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "spannora-monorepo",
3-
"version": "0.6.0",
3+
"version": "0.6.1",
44
"private": true,
55
"description": "Self-hosted web chat for Claude Code (Agent SDK). Server + hub PWA + shared frontend modules.",
66
"workspaces": [

0 commit comments

Comments
 (0)