decolua/9router · critical
[DB] No SQLite driver available (bun/better/node/sql.js all
Error message
[DB] No SQLite driver available (bun/better/node/sql.js all failed)
What it means
initAdapter walks a fallback chain of SQLite backends — bun:sqlite, better-sqlite3, node:sqlite, and the pure-JS sql.js — and throws this error only when every one fails to initialize. It means the process has no usable way to open DATA_FILE, so all DB-backed features are down. Each attempt is logged upstream; the throw happens after the last (sql.js) attempt also returns null.
Source
Thrown at src/lib/db/driver.js:64
try {
const { createSqlJsAdapter } = await import("./adapters/sqljsAdapter.js");
return await createSqlJsAdapter(DATA_FILE);
} catch (e) {
console.warn(`[DB] sql.js unavailable: ${e.message}`);
return null;
}
}
async function initAdapter() {
ensureDirs();
// Order per runtime:
// Bun: bun:sqlite → sql.js
// Node: better-sqlite3 → node:sqlite (≥22.5) → sql.js
let adapter = await tryBunSqlite();
if (!adapter) adapter = await tryBetterSqlite();
if (!adapter) adapter = await tryNodeSqlite();
if (!adapter) adapter = await trySqlJs();
if (!adapter) throw new Error("[DB] No SQLite driver available (bun/better/node/sql.js all failed)");
if (!state.logged) {
console.log(`[DB] Driver: ${adapter.driver} | file: ${DATA_FILE}`);
state.logged = true;
}
const { runMigrationOnce } = await import("./migrate.js");
await runMigrationOnce(adapter);
return adapter;
}
export async function getAdapter() {
if (state.instance) return state.instance;
if (!state.initPromise) state.initPromise = initAdapter().then((a) => { state.instance = a; return a; });
return state.initPromise;
}
export function getAdapterSync() {View on GitHub (pinned to 90b52e06ff)
Solutions
- Reinstall with optionals enabled: `npm install` (not --omit=optional) so better-sqlite3 is built, and check its install/build logs.
- On Node >= 22.5 prefer node:sqlite; upgrade Node or set DATA_DIR to a writable path if the file open was the failure point.
- Check earlier log lines from tryBunSqlite/tryBetterSqlite/tryNodeSqlite/trySqlJs to see each driver's specific failure (module not found vs. SQLITE_CANTOPEN vs. WASM load).
- Ensure DATA_DIR (default ~/.9router) exists and is writable by the process user; fix permissions or point DATA_DIR elsewhere and restart.
- As a last resort verify sql.js is resolvable (it is the always-works fallback) — if even it fails, the dependency tree or WASM assets are broken and a clean reinstall is needed.
Example fix
// before npm ci --omit=optional # better-sqlite3 never installed; no driver loads // after npm install # optional deps built; [DB] Driver: better-sqlite3 | file: ~/.9router/db.sqlite
Defensive patterns
Strategy: fallback
Validate before calling
async function assertSqliteAvailable() {
try { const a = await getAdapter(); return !!a; }
catch (err) {
if (String(err.message).includes('No SQLite driver available')) return false;
throw err;
}
}
// call at startup: if (!(await assertSqliteAvailable())) show fatal setup error Try / catch
try {
const db = await getAdapter();
} catch (err) {
if (String(err.message).includes('[DB] No SQLite driver available')) {
console.error('Fatal: no SQLite backend. Reinstall with `npm install` so better-sqlite3 builds, or run on Node >=22.5 / Bun.');
process.exit(1);
}
throw err;
} Prevention
- Install with optional dependencies enabled so better-sqlite3 (the preferred native driver) is built on Node.
- Pin/upgrade to Node >= 22.5 (built-in node:sqlite) or run under Bun (bun:sqlite) to remove the native-build dependency.
- Ensure DATA_DIR (default ~/.9router) exists and is writable before startup; a bad file path makes every driver fail.
- After Node major upgrades, rebuild native modules (npm rebuild better-sqlite3) to avoid ABI mismatches.
- Check the per-driver failure logs printed before the throw — they distinguish 'module missing' from 'cannot open database file'.
When it happens
Trigger: Running on Node without better-sqlite3 installed/buildable, Node <22.5 (no node:sqlite), not on Bun, and sql.js unavailable (missing dependency or WASM load failure).
Common situations: npm install skipped optionalDependencies (--omit=optional) so better-sqlite3 native build never ran; native module ABI mismatch after a Node major upgrade; constrained/alpine containers lacking build tools for node-gyp; a corrupted or unwritable DATA_DIR/`~/.9router` making every driver fail to open the file; exotic runtimes (Edge, Electron renderer) where none of the drivers load.
Related errors
- [DB] bun:sqlite unavailable: ${e.message}
- [DB] node:sqlite unavailable: ${e.message}
- [DB][sync] add column ${tableName}.${colName} failed: ${e.me
- [DB][migrate] pre-schema backup failed (continuing): ${e.mes
- Failed to export database
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/9c05b222b56e726c.
Report an issue: GitHub.