From 94e1cc9a4e4b4d4b6dbcc9ee7fdc202f025817d0 Mon Sep 17 00:00:00 2001 From: cxbAsDev Date: Sat, 18 Jul 2026 17:02:28 +0800 Subject: [PATCH] fix(daemon): distinguish shared and embedded SQLite in system Node warning (#107990) --- src/daemon/runtime-paths.test.ts | 29 +++++++++++++++++++++++++++-- src/daemon/runtime-paths.ts | 18 ++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/daemon/runtime-paths.test.ts b/src/daemon/runtime-paths.test.ts index 4e6abfed4018..cbb868d0cacb 100644 --- a/src/daemon/runtime-paths.test.ts +++ b/src/daemon/runtime-paths.test.ts @@ -45,9 +45,13 @@ function mockNodePathPresent(...nodePaths: string[]) { }); } -function nodeRuntime(nodeVersion: string, sqliteVersion: string | null = "3.51.3") { +function nodeRuntime( + nodeVersion: string, + sqliteVersion: string | null = "3.51.3", + nodeSharedSqlite = false, +) { return { - stdout: `${JSON.stringify({ nodeVersion, sqliteVersion })}\n`, + stdout: `${JSON.stringify({ nodeVersion, sqliteVersion, nodeSharedSqlite })}\n`, stderr: "", }; } @@ -402,6 +406,7 @@ describe("resolveSystemNodeInfo", () => { path: darwinNode, sqliteVersion: "3.51.3", version: "22.22.3", + nodeSharedSqlite: false, supported: true, }); }); @@ -432,6 +437,7 @@ describe("resolveSystemNodeInfo", () => { path: homebrewOptNode, sqliteVersion: "3.51.3", version: "22.22.3", + nodeSharedSqlite: false, supported: true, }); }); @@ -456,6 +462,7 @@ describe("resolveSystemNodeInfo", () => { path: homebrewOptNode, sqliteVersion: "3.51.3", version: "24.15.0", + nodeSharedSqlite: false, supported: true, }); expect(execFile).toHaveBeenCalledTimes(1); @@ -490,6 +497,7 @@ describe("resolveSystemNodeInfo", () => { path: darwinNode, sqliteVersion: null, version: "18.19.0", + nodeSharedSqlite: false, supported: false, }, "/Users/me/.fnm/node-22/bin/node", @@ -504,11 +512,28 @@ describe("resolveSystemNodeInfo", () => { path: darwinNode, sqliteVersion: "3.51.2", version: "24.17.0", + nodeSharedSqlite: false, supported: false, }); expect(warning).toContain("uses SQLite 3.51.2"); expect(warning).toContain("not WAL-reset-safe"); + expect(warning).toContain("Install Node 24.15+"); + }); + + it("renders a shared-system-SQLite remediation when Node is supported but the system library is unsafe", () => { + const warning = renderSystemNodeWarning({ + path: "/usr/bin/node", + sqliteVersion: "3.51.2", + version: "24.17.0", + nodeSharedSqlite: true, + supported: false, + }); + + expect(warning).toContain("uses shared system SQLite 3.51.2"); + expect(warning).toContain("not WAL-reset-safe"); + expect(warning).toContain("Upgrade the system SQLite library"); + expect(warning).not.toContain("Install Node 24.15+"); }); it("uses validated custom Program Files roots on Windows", async () => { diff --git a/src/daemon/runtime-paths.ts b/src/daemon/runtime-paths.ts index bb5a90a95eae..f30bcdab684d 100644 --- a/src/daemon/runtime-paths.ts +++ b/src/daemon/runtime-paths.ts @@ -94,12 +94,15 @@ try { db.close(); } } catch {} -process.stdout.write(JSON.stringify({ nodeVersion: process.versions.node, sqliteVersion })); +const variables = (process.config && process.config.variables) || {}; +const nodeSharedSqlite = variables.node_shared_sqlite === true || variables.node_shared_sqlite === "true"; +process.stdout.write(JSON.stringify({ nodeVersion: process.versions.node, sqliteVersion, nodeSharedSqlite })); `; type NodeRuntimeInfo = { nodeVersion: string | null; sqliteVersion: string | null; + nodeSharedSqlite: boolean; supported: boolean; }; @@ -115,19 +118,22 @@ async function resolveNodeRuntimeInfo( const parsed = JSON.parse(stdout) as { nodeVersion?: unknown; sqliteVersion?: unknown; + nodeSharedSqlite?: unknown; }; const nodeVersion = typeof parsed.nodeVersion === "string" ? parsed.nodeVersion : null; const sqliteVersion = typeof parsed.sqliteVersion === "string" ? parsed.sqliteVersion : null; + const nodeSharedSqlite = parsed.nodeSharedSqlite === true || parsed.nodeSharedSqlite === "true"; return { nodeVersion, sqliteVersion, + nodeSharedSqlite, supported: isSupportedNodeVersion(nodeVersion) && sqliteVersion !== null && isSqliteWalResetSafeVersion(sqliteVersion), }; } catch { - return { nodeVersion: null, sqliteVersion: null, supported: false }; + return { nodeVersion: null, sqliteVersion: null, nodeSharedSqlite: false, supported: false }; } } @@ -135,6 +141,7 @@ type SystemNodeInfo = { path: string; sqliteVersion: string | null; version: string | null; + nodeSharedSqlite: boolean; supported: boolean; }; @@ -214,6 +221,7 @@ export async function resolveSystemNodeInfo(params: { path: systemNode, sqliteVersion: runtime.sqliteVersion, version: runtime.nodeVersion, + nodeSharedSqlite: runtime.nodeSharedSqlite, supported: runtime.supported, }; if (info.supported) { @@ -236,6 +244,12 @@ export function renderSystemNodeWarning( const selectedLabel = selectedNodePath ? ` Using ${selectedNodePath} for the daemon.` : ""; if (isSupportedNodeVersion(systemNode.version)) { const sqliteLabel = systemNode.sqliteVersion ?? "unknown"; + if (systemNode.nodeSharedSqlite) { + return ( + `System Node ${versionLabel} at ${systemNode.path} uses shared system SQLite ${sqliteLabel}, which is not WAL-reset-safe.${selectedLabel} ` + + "Upgrade the system SQLite library to 3.51.3+ (or patched 3.50.7+/3.44.6+), or install a Node build that embeds a safe version." + ); + } return `System Node ${versionLabel} at ${systemNode.path} uses SQLite ${sqliteLabel}, which is not WAL-reset-safe.${selectedLabel} Install Node 24.15+ (recommended) or Node 22.22.3+ from nodejs.org or Homebrew.`; } return `System Node ${versionLabel} at ${systemNode.path} is outside the supported range.${selectedLabel} Install Node 24.15+ (recommended) or Node 22.22.3+ from nodejs.org or Homebrew.`;