From 68a883f0c651c809f2207d736d354149ac47e24d Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Tue, 21 Jul 2026 08:39:43 -0300 Subject: [PATCH] fix(cli): translate missing sqlite bindings error into actionable guidance (#7868) (#7963) createSqliteNativeError() in bin/cli/sqlite.mjs only recognized the ABI-mismatch native error class (NODE_MODULE_VERSION/ERR_DLOPEN_FAILED). It silently passed through the 'Could not locate the bindings file' class thrown by the bindings package when the better-sqlite3 native addon was never built/downloaded - the exact case hit by 'npx omniroute reset-password', since npx runs a fresh ephemeral install that never builds the addon. Users got a raw multi-line path dump instead of guidance. Widen the condition to also match 'Could not locate the bindings file', MODULE_NOT_FOUND, and "Cannot find module 'better-sqlite3'", and point users at the existing self-heal command `omniroute runtime repair`, same as the ABI-mismatch branch already does. Regression test: tests/unit/cli-sqlite-bindings-not-found-7868.test.ts - RED against the reporter's exact error text before the fix, GREEN after. --- bin/cli/sqlite.mjs | 12 +++++++ .../7868-reset-password-sqlite-bindings.md | 1 + ...cli-sqlite-bindings-not-found-7868.test.ts | 31 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 changelog.d/fixes/7868-reset-password-sqlite-bindings.md create mode 100644 tests/unit/cli-sqlite-bindings-not-found-7868.test.ts diff --git a/bin/cli/sqlite.mjs b/bin/cli/sqlite.mjs index 9502b0aedb..923903b404 100644 --- a/bin/cli/sqlite.mjs +++ b/bin/cli/sqlite.mjs @@ -21,6 +21,18 @@ export function createSqliteNativeError(error) { "(rebuilds into a user-writable runtime; works without a C++ toolchain)." ); } + if ( + message.includes("Could not locate the bindings file") || + message.includes("MODULE_NOT_FOUND") || + message.includes("Cannot find module 'better-sqlite3'") + ) { + return new Error( + "better-sqlite3 native binding could not be found (no prebuilt addon for this platform). " + + "This is common under `npx`, which runs a fresh, ephemeral install that never built the addon. " + + "Run: omniroute runtime repair " + + "(rebuilds into a user-writable runtime; works without a C++ toolchain)." + ); + } return error; } diff --git a/changelog.d/fixes/7868-reset-password-sqlite-bindings.md b/changelog.d/fixes/7868-reset-password-sqlite-bindings.md new file mode 100644 index 0000000000..63f6b31313 --- /dev/null +++ b/changelog.d/fixes/7868-reset-password-sqlite-bindings.md @@ -0,0 +1 @@ +- fix(cli): translate missing better-sqlite3 native bindings error into actionable `omniroute runtime repair` guidance in `reset-password`/setup CLI commands (#7868) diff --git a/tests/unit/cli-sqlite-bindings-not-found-7868.test.ts b/tests/unit/cli-sqlite-bindings-not-found-7868.test.ts new file mode 100644 index 0000000000..1ccd7c9ebc --- /dev/null +++ b/tests/unit/cli-sqlite-bindings-not-found-7868.test.ts @@ -0,0 +1,31 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { createSqliteNativeError } from "../../bin/cli/sqlite.mjs"; + +test("#7868: createSqliteNativeError() gives actionable guidance for a missing-bindings-file error", () => { + const rawBindingsError = new Error( + "Could not locate the bindings file. Tried:\n" + + " → /Users/agent_user/.npm/_npx/44b85dff014d9ceb/node_modules/better-sqlite3/build/better_sqlite3.node\n" + + " → /Users/agent_user/.npm/_npx/44b85dff014d9ceb/node_modules/better-sqlite3/build/Release/better_sqlite3.node\n" + + " → /Users/agent_user/.npm/_npx/44b85dff014d9ceb/node_modules/better-sqlite3/lib/binding/node-v147-darwin-arm64/better_sqlite3.node" + ); + + const translated = createSqliteNativeError(rawBindingsError); + + assert.notStrictEqual( + translated.message, + rawBindingsError.message, + "createSqliteNativeError() passed the raw 'Could not locate the bindings file' dump through " + + "unchanged instead of translating it into actionable guidance (#7868)" + ); + assert.match( + translated.message, + /runtime repair/i, + "translated error should point the user at the existing self-heal command " + + "(`omniroute runtime repair`), same as the ABI-mismatch branch already does" + ); + assert.ok( + !translated.message.includes("Tried:"), + "a raw path dump reaching the user is itself a signal the fix regressed" + ); +});