remix-run/remix · error · Error

SQLite database + method + () requires config-based constru

Error message

SQLite database  + method + () requires config-based construction

What it means

Mirror of the Postgres driver behavior: SQLite driver methods that need the original config (such as reopening/wiping the database) throw when the driver was constructed from an existing database client, because no filename/config is available to act on.

Source

Thrown at packages/data-table-sqlite/src/lib/driver.ts:449

      this.#databaseOpen = false
      this.#database.close?.()
    }
  }

  #discardUncertainConnection(): void {
    if (this.#config) {
      this.#closeDatabase()
      this.#replaceDatabase()
    } else {
      // The supplied client remains caller-owned, but this wrapper cannot safely
      // reuse a connection whose transaction state is unknown.
      this.#databaseOpen = false
    }
  }

  #configOrThrow(method: string): SqliteDatabaseConfig {
    if (!this.#config) {
      throw new Error('SQLite database ' + method + '() requires config-based construction')
    }

    return this.#config
  }

  #assertNoOpenTransactions(method: string): void {
    if (this.#transactions.size > 0) {
      throw new Error('SQLite database cannot ' + method + ' while transactions are open')
    }
  }

  #assertTransaction(token: TransactionToken): void {
    this.#assertDatabaseOpen()
    if (!this.#transactions.has(token.id)) {
      throw new Error('Unknown transaction token: ' + token.id)
    }
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Construct with a config ({ filename: ... }) when you need administrative operations
  2. Pass the filename so the driver can reopen/reset the database itself
  3. For tests, use a config-based driver pointing at a temp file instead of an injected client

Example fix

// before
new SqliteDatabase(new DatabaseSync(':memory:'))
await db.wipe() // throws

// after
new SqliteDatabase({ filename: './test.db' })
await db.wipe()
Defensive patterns

Strategy: validation

Validate before calling

// choose construction based on need
let db = needsAdminOps ? new SqliteDatabase({ filename: path }) : new SqliteDatabase(client)

Prevention

When it happens

Trigger: Constructing SqliteDatabase with a client instance (injected for tests or shared pools) and then calling a config-requiring method (the method named in the message, e.g. wipe).

Common situations: Test suites injecting an in-memory client then calling wipe() between tests; sharing one open DatabaseSync across modules and later needing destructive reset.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/1cabb1ec2b520450. Report an issue: GitHub.