From 2f1b9151f3e521ddcd3b14c4ecf22d1a98fadef9 Mon Sep 17 00:00:00 2001 From: Oleksii Nikiforov Date: Fri, 26 Jun 2026 13:38:20 +0300 Subject: [PATCH] fix: create sqlite db parent directory before opening node:sqlite does not create missing parent directories and fails with "unable to open database file". The default db path resolves under the package dir, which ships no data/ folder, so sideshow serve crashed on first run. Create the parent dir before opening the database. --- .changeset/sqlite-mkdir-parent.md | 2 ++ server/sqliteStorage.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/sqlite-mkdir-parent.md diff --git a/.changeset/sqlite-mkdir-parent.md b/.changeset/sqlite-mkdir-parent.md new file mode 100644 index 0000000..a845151 --- /dev/null +++ b/.changeset/sqlite-mkdir-parent.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/server/sqliteStorage.ts b/server/sqliteStorage.ts index fa604a1..f197947 100644 --- a/server/sqliteStorage.ts +++ b/server/sqliteStorage.ts @@ -1,4 +1,5 @@ -import { existsSync } from "node:fs"; +import { existsSync, mkdirSync } from "node:fs"; +import { dirname } from "node:path"; import { JsonFileStore } from "./storage.ts"; import { SqlStore } from "./sqlStore.ts"; import type { SqlStorage, SqlStorageCursor, SqlStorageValue } from "./types.ts"; @@ -41,6 +42,12 @@ function makeCursor(rows: Record[]): SqlStorageCursor { // path. `:memory:` (the default) backs the store-contract suite; a file path is // the real local store. export function createSqliteStorage(path = ":memory:"): SqlStorage { + if (path !== ":memory:") { + // node:sqlite won't create missing parent directories — it just fails with + // "unable to open database file". The default db path lives under the + // package dir (no `data/` shipped), so the first run would always crash. + mkdirSync(dirname(path), { recursive: true }); + } const db = new DatabaseSync(path); if (path !== ":memory:") { // WAL + NORMAL: durable across a crash, far fewer fsyncs than the default