Skip to content

fix(nix): pin dev shell to nodejs_24 and add python3 - #14613

Merged
diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.51from
marcothedood:fix/nix-devshell-better-sqlite3
Sep 24, 2026
Merged

diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.51from
marcothedood:fix/nix-devshell-better-sqlite3

Conversation

@marcothedood

Copy link
Copy Markdown
Contributor

⚠️ base-red inherited: #14547

Problem

A clean git clone + nix develop on macOS (aarch64-darwin) ends with the postinstall.mjs banner and no SQLite driver:

  🔴 CRITICAL: 'better-sqlite3' is missing from node_modules/

The banner blames npm ≥ 11 blocking install scripts, but the shell was running npm 10.9.7, so the suggested fixes do not apply.

Root cause

better-sqlite3 ships a binding.gyp and no install script, so npm runs node-gyp rebuild for it automatically. On macOS without Xcode Command Line Tools, /usr/bin/python3 is a stub that cannot exec (error: tool 'python3' not found), and the dev shell provides no Python:

> better-sqlite3@13.0.3 install
> node-gyp rebuild
gyp ERR! find Python checking if "python3" can be used
gyp ERR! find Python - executable path is ""
gyp ERR! stack Error: Could not find any Python installation to use

better-sqlite3 is an optionalDependency, so npm drops it silently — the install reports success and only postinstall.mjs notices.

Second, unrelated defect found in the same run: nodejs_22 ships npm 10, which rewrites package-lock.json on every install — it strips the npm 11 libc fields and downgrades undici 7.29.1 → 6.28.1 (221 deletions). Committing that would regress the lockfile for everyone.

Fix

flake.nix only:

  • nodejs_22 → nodejs_24 (npm 11.13.0 on nixos-25.11). npm 11 does not run unapproved install scripts, so the bundled prebuilds/darwin-arm64.node is used instead of a source build, and the lockfile stays byte-identical. engines already allows >=24.0.0 <27.
  • add pkgs.python3 so any genuine from-source native build has a working interpreter.

Test plan

Reproduce the failure on release/v3.8.51:

rm -rf node_modules && git checkout package-lock.json
nix develop --command npm install --foreground-scripts 2>&1 | grep -A3 "better-sqlite3@13.0.3 install"
ls -d node_modules/better-sqlite3          # missing
git diff --stat package-lock.json          # 16 insertions(+), 221 deletions(-)

With this branch:

rm -rf node_modules && git checkout package-lock.json
nix develop --command npm install
ls -d node_modules/better-sqlite3          # present
node -e "const D=require('better-sqlite3');console.log(new D(':memory:').prepare('select 1 a').get())"
git diff --stat package-lock.json          # no output
nix develop --command node scripts/build/postinstall.mjs   # no CRITICAL banner

Verified on aarch64-darwin (macOS 27.0.0, nixpkgs nixos-25.11): node v24.16.0, npm 11.13.0, Python 3.13.12, better-sqlite3 loads, lockfile untouched.

Notes

No production code under src/, open-sse/, electron/ or bin/ is touched, so the PR test policy does not apply — the reproduction is the shell transcript above.

#13076 also edits flake.nix (Nix packaging / FOD, cc @Ansh-Sonkusare). The two changes are independent — that PR touches the packages output, this one the devShells.default input list — but they will textually conflict. Happy to rebase on top of #13076 whenever it lands, or to fold this into it if you prefer a single Nix PR.

better-sqlite3 has a binding.gyp and no install script, so npm runs
`node-gyp rebuild` for it. macOS /usr/bin/python3 is an Xcode CLT stub
that cannot exec, node-gyp aborts with "Could not find any Python
installation to use", and npm silently prunes the package because it is
an optionalDependency. `nix develop` then ends on the postinstall.mjs
CRITICAL banner with no working SQLite driver.

nodejs_22 also ships npm 10, which rewrites package-lock.json on every
install: it drops the npm 11 `libc` fields and downgrades undici 7.29.1
to 6.28.1 (221 deletions).

nodejs_24 ships npm 11, which does not run unapproved install scripts,
so the bundled prebuilds/darwin-arm64.node is used and the lockfile stays
byte-identical. python3 is kept in the shell for any from-source native
build. engines allow >=24.0.0 <27.
Ansh-Sonkusare added a commit to Ansh-Sonkusare/OmniRoute that referenced this pull request Sep 23, 2026
The npm version changes what `npm install -g` produces, so it is part of
the fixed-output hash. Build the package with nodejs_24 (npm 11), matching
the dev shell fix proposed in cheaper-inference#14613, and recompute the hash: the Node 22
hash no longer matches under npm 11.

Only the package is pinned. The shared `nodejs` binding used by the dev
shell is left untouched so this does not conflict with cheaper-inference#14613.

Verified on x86_64-linux with Node 24.16.0: `nix build .#default`
succeeds, the server starts from the store, and login plus password and
settings changes work and persist across a restart.
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thorough root-cause writeup and a great before/after repro — confirmed nodejs_24 is already
available in the pinned nixos-25.11 revision (no flake.lock bump needed) and that
package.json's engines already allows it. No production code touched, so the manual repro
transcript is the right validation here. Noted the textual (not logical) conflict with #13076's
flake.nix change in a different section (packages vs devShells) for the merge queue —
merging this one first since it fixes an active onboarding blocker. Thanks for flagging that
proactively.

@diegosouzapw
diegosouzapw merged commit be877f5 into cheaper-inference:release/v3.8.51 Sep 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants