{"record":{"id":"f37ea7dd6a14fb65","repo":"payloadcms/payload","slug":"error-cannot-connect-to-sqlite-message-f37ea7","errorCode":null,"errorMessage":"Error: cannot connect to SQLite: ${message}","messagePattern":"Error: cannot connect to SQLite: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/db-sqlite/src/connect.ts","lineNumber":57,"sourceCode":"    }\n\n    const logger = this.logger || false\n    this.drizzle = drizzle(this.client, { logger, schema: this.schema })\n\n    if (!hotReload) {\n      if (process.env.PAYLOAD_DROP_DATABASE === 'true') {\n        this.payload.logger.info(`---- DROPPING TABLES ----`)\n        await this.dropDatabase({ adapter: this })\n        this.payload.logger.info('---- DROPPED TABLES ----')\n      }\n    }\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err)\n    this.payload.logger.error({ err, msg: `Error: cannot connect to SQLite: ${message}` })\n    if (typeof this.rejectInitializing === 'function') {\n      this.rejectInitializing()\n    }\n    throw new Error(`Error: cannot connect to SQLite: ${message}`)\n  }\n\n  // Only push schema if not in production\n  if (\n    process.env.NODE_ENV !== 'production' &&\n    process.env.PAYLOAD_MIGRATING !== 'true' &&\n    this.push !== false\n  ) {\n    await pushDevSchema(this as unknown as DrizzleAdapter)\n  }\n\n  if (typeof this.resolveInitializing === 'function') {\n    this.resolveInitializing()\n  }\n\n  if (process.env.NODE_ENV === 'production' && this.prodMigrations) {\n    await this.migrate({ migrations: this.prodMigrations as Migration[] })\n  }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/db-sqlite/src/connect.ts#L39-L75","documentation":"Thrown by the SQLite (db-sqlite) adapter's `connect` after `better-sqlite3` fails to open the database. The adapter logs the message, rejects the init promise, and re-throws a wrapped Error so `payload.init()` rejects.","triggerScenarios":"The SQLite file path is unwritable or its directory doesn't exist, the file is locked by another process, the native binding is missing/incompatible (Node ABI mismatch), or the file is corrupt.","commonSituations":"Relative or wrong `dbPath`; target directory missing or read-only; file permissions; Node version vs better-sqlite3 prebuilt binary mismatch; file on a read-only/serverless filesystem; another process holds an exclusive lock.","solutions":["Make `dbPath` absolute and confirm its parent directory exists and is writable.","Rebuild the native binding for your Node ABI: `npm rebuild better-sqlite3` (or reinstall).","Ensure no other process holds an exclusive lock on the file.","On serverless/read-only filesystems, place the DB on a writable volume."],"exampleFix":"// before\nsqliteAdapter({ client: { url: file:./db.sqlite } }) // relative, dir missing\n// after\nimport { mkdirSync } from 'fs'\nmkdirSync('/data', { recursive: true })\nsqliteAdapter({ client: { url: 'file:/data/db.sqlite' } })","handlingStrategy":"validation","validationCode":"function assertSqliteWritable(dbPath) {\n  const dir = path.dirname(path.resolve(dbPath))\n  fs.mkdirSync(dir, { recursive: true })\n  fs.accessSync(dir, fs.constants.W_OK)\n}","typeGuard":"const isAbsoluteWritablePath = (p) => path.isAbsolute(p)","tryCatchPattern":"try { await payload.init() }\ncatch (e) { if (/cannot connect to SQLite/.test(e.message)) { await rebuildBetterSqlite() } else throw e }","preventionTips":["Use an absolute dbPath and ensure its directory exists and is writable.","After Node upgrades, run `npm rebuild better-sqlite3`.","Avoid placing the SQLite file on a read-only filesystem.","Ensure no other process holds an exclusive lock on the file."],"tags":["sqlite","connection","startup","native-binding","config"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}