remix-run/remix · error · Error
MySQL database + method + () requires config-based construc
Error message
MySQL database + method + () requires config-based construction
What it means
The MySQL driver supports two construction modes: config-based (pool-managed) and client-based (external connection). Methods that need to create or manage the pool — signalled by #configOrThrow — throw this error when called on a driver built from an existing client, because there is no config to build a pool from.
Source
Thrown at packages/data-table-mysql/src/lib/driver.ts:477
// tracked to keep close() idempotent.
if (isMysqlPool(this.#client) && !this.#poolClosed) {
this.#poolClosed = true
await this.#client.end()
}
}
async #replacePool(): Promise<void> {
await this.#closePool().catch(() => undefined)
if (this.#config) {
this.#client = createMysqlPool(this.#config)
this.#poolClosed = false
}
}
#configOrThrow(method: string): string | MysqlPoolOptions {
if (!this.#config) {
throw new Error('MySQL database ' + method + '() requires config-based construction')
}
return this.#config
}
#assertNoOpenTransactions(method: string): void {
if (this.#transactions.size > 0) {
throw new Error('MySQL database cannot ' + method + ' while transactions are open')
}
}
#resolveClient(token: TransactionToken | undefined): MysqlQueryable {
if (!token) {
return this.#client
}
return this.#transactionConnection(token)
}View on GitHub (pinned to 9696913134)
Solutions
- Construct the driver from a config object (host/user/password/database or uri) so pool-managing methods work
- If you must keep the external client, avoid the pool-requiring method and perform the equivalent operation directly on your client
- Check the method name in the error message to identify which call needs config
Example fix
// before
const driver = createMysqlDriver(existingClient)
await driver.wipe()
// after
const driver = createMysqlDriver({ uri: MYSQL_URI })
await driver.wipe() Defensive patterns
Strategy: validation
Validate before calling
// Decide based on construction mode before calling pool-requiring methods
const driverFromConfig = createMysqlDriver({ uri: process.env.MYSQL_URL! })
// use driverFromConfig for wipe()/pool lifecycle; keep client-based drivers for scoped queries Try / catch
try { await driver.wipe() } catch (e) { if (e instanceof Error && e.message.includes('requires config-based construction')) { /* rebuild driver from config or clean manually */ } throw e } Prevention
- Use config-based construction when you need lifecycle management
- Reserve client-based drivers for injected-connection scenarios without wipe/pool calls
When it happens
Trigger: Constructing the driver with new MysqlDriver(client) (or an equivalent client-injection factory) and then calling a pool-requiring method such as connect/config-dependent lifecycle operations; typically surfaced via a method named in the message, e.g. 'MySQL database wipe() requires config-based construction'.
Common situations: Using an injected client for tests or a managed connection, then calling wipe/reset/pool operations during teardown; switching from config-based to client-based construction without auditing lifecycle calls.
Related errors
- MySQL database config requires a database name
- Unknown transaction token: + token.id
- MySQL migration lock is already held by this database
- MySQL database cannot + method + while transactions are op
- MySQL migration lock could not be acquired
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/fddb2d915b4d096e.
Report an issue: GitHub.