Skip to content

[Bug]: SQLite ":memory:" config fails because colon is stripped but Bun connector expects it #3633

@malformed-c

Description

@malformed-c

Environment

Operating system Linux 6.17.9-zen1-1-zen
CPU Intel(R) Core(TM) i5-8365U CPU @ 1.60GHz (8 cores)
Node.js version v25.2.1
nuxt/cli version 3.31.2-20251205-111428-3650f92
Package manager [email protected]
Nuxt version 4.2.2-29413365.2a912219
Nitro version 2.12.9
Builder [email protected]
Config app, colorMode, compatibilityDate, content, css, devtools, experimental, fonts, modules, nitro, routeRules, runtimeConfig, svgo, ui, vite
Modules @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], [email protected]

Version

v3

Reproduction

I'll provide the repository if needed.

  1. Configure Nuxt Content with sqlite and filename: ":memory:".
  2. Run in a read-only environment (or Docker container).
  3. Observe SQLITE_CANTOPEN error because it tries to write to disk instead of using memory.

Description

I am deploying Nuxt Content v3 on Kubernetes using the Bun runtime. I am trying to use an in-memory SQLite database to avoid file system permission issues in the container.
However, setting filename: ":memory:" triggers a logic error where the configuration parser strips the colon, but the connector checks strictly for ":memory:". This causes the application to fall through to the file-system creation logic, attempting to write a file named .data/memory.bun.sqlite, which it's unable to do due to permissions.

Additional context

related snippet 1

function refineDatabaseConfig(config) {
...
  if (config.type === "sqlite") {
    const _config = { ...config };
    if (config.filename === ":memory:") {
      return { name: "memory" }; // <--- Returns "memory" without colon
    }
    if ("filename" in config) {
      const filename = isAbsolute(config?.filename || "") || config?.filename === ":memory:" ? config?.filename : new URL(config.filename, globalThis._importMeta_.url).pathname;
      _config.path = process.platform === "win32" && filename.startsWith("/") ? filename.slice(1) : filename;
    }
    return _config;
  }

related snippet 2

function bunSqliteConnector(opts) {
  let _db;
  const getDB = () => {
    if (_db) {
      return _db;
    }
    if (opts.name === ":memory:") { // <--- Checks for ":memory:"
      _db = new Database(":memory:");
    } else {
      const filePath = resolve$1(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
      mkdirSync(dirname$1(filePath), { recursive: true });
      _db = new Database(filePath);
    }
    return _db;
  };

Logs

[request error] [unhandled] [POST] http://localhost/__nuxt_content/faq/query?v=v3.5.0--uOI5oD1lVvnPvQrq99B90r2Ef0ddCNWLK-rmPNHVtbk
 7170 |                 if (opts.name === ":memory:") {
7171 |                  _db = new Database(":memory:");
7172 |          } else {
7173 |                  const filePath = resolve$1(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
7174 |                  mkdirSync(dirname$1(filePath), { recursive: true });
7175 |                  _db = new Database(filePath);
       ^
error: unable to open database file
 statusCode: 500,
      fatal: false,
  unhandled: true,
 statusMessage: undefined,
       data: undefined,

      at open (unknown:1:1)
      at new Database (bun:sqlite:260:28)
      at getDB (/app/.output/server/index.mjs:7175:14)
      at prepare (/app/.output/server/index.mjs:7731:3)
      at /app/.output/server/index.mjs:7846:17
      at all (/app/.output/server/index.mjs:7844:14)
      at processTicksAndRejections (native:7:39)

7170 |          if (opts.name === ":memory:") {
7171 |                  _db = new Database(":memory:");
7172 |          } else {
7173 |                  const filePath = resolve$1(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
7174 |                  mkdirSync(dirname$1(filePath), { recursive: true });
7175 |                  _db = new Database(filePath);
       ^
SQLiteError: unable to open database file
      errno: 14,
 byteOffset: -1,
       code: "SQLITE_CANTOPEN"

      at open (unknown:1:1)
      at new Database (bun:sqlite:260:28)
      at getDB (/app/.output/server/index.mjs:7175:14)
      at prepare (/app/.output/server/index.mjs:7731:3)
      at /app/.output/server/index.mjs:7846:17
      at all (/app/.output/server/index.mjs:7844:14)
      at processTicksAndRejections (native:7:39)

[request error] [unhandled] [POST] http://localhost/__nuxt_content/help/query?v=v3.5.0--R4Jkm8iUOdTraAOZDik1Qabjbov03KYvkgl3N6Wk-xk
 7170 |                 if (opts.name === ":memory:") {
7171 |                  _db = new Database(":memory:");
7172 |          } else {
7173 |                  const filePath = resolve$1(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
7174 |                  mkdirSync(dirname$1(filePath), { recursive: true });
7175 |                  _db = new Database(filePath);
       ^
error: unable to open database file
 statusCode: 500,
      fatal: false,
  unhandled: true,
 statusMessage: undefined,
       data: undefined,

      at open (unknown:1:1)
      at new Database (bun:sqlite:260:28)
      at getDB (/app/.output/server/index.mjs:7175:14)
      at prepare (/app/.output/server/index.mjs:7731:3)
      at /app/.output/server/index.mjs:7846:17
      at all (/app/.output/server/index.mjs:7844:14)
      at processTicksAndRejections (native:7:39)

7170 |          if (opts.name === ":memory:") {
7171 |                  _db = new Database(":memory:");
7172 |          } else {
7173 |                  const filePath = resolve$1(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
7174 |                  mkdirSync(dirname$1(filePath), { recursive: true });
7175 |                  _db = new Database(filePath);
       ^
SQLiteError: unable to open database file
      errno: 14,
 byteOffset: -1,
       code: "SQLITE_CANTOPEN"

      at open (unknown:1:1)
      at new Database (bun:sqlite:260:28)
      at getDB (/app/.output/server/index.mjs:7175:14)
      at prepare (/app/.output/server/index.mjs:7731:3)
      at /app/.output/server/index.mjs:7846:17
      at all (/app/.output/server/index.mjs:7844:14)
      at processTicksAndRejections (native:7:39)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions