tursodatabase/turso · error · TypeError
The database connection is not open
Error message
The database connection is not open
What it means
Connection.prepare() checks the private isOpen flag and throws a plain TypeError 'The database connection is not open' when the connection has been closed. close() sets isOpen = false before closing the session, and there is no public isOpen getter on Connection, so callers must track lifecycle themselves or use reconnect() to reopen the same object.
Source
Thrown at serverless/javascript/src/connection.ts:153
/**
* Prepare a SQL statement for execution.
*
* Prepared statements created from a Connection use the same underlying session so transaction boundaries are preserved.
* This method fetches column metadata using the describe functionality.
*
* @param sql - The SQL statement to prepare
* @returns A Promise that resolves to a Statement object with column metadata
*
* @example
* ```typescript
* const stmt = await client.prepare("SELECT * FROM users WHERE id = ?");
* const columns = stmt.columns();
* const user = await stmt.get([123]);
* ```
*/
async prepare(sql: string): Promise<Statement> {
if (!this.isOpen) {
throw new TypeError("The database connection is not open");
}
// Describe on the existing session so it sees uncommitted DDL
// (e.g. CREATE TABLE in the same transaction).
await this.execLock.acquire();
let description;
try {
description = await this.session.describe(sql);
} finally {
this.execLock.release();
}
const stmt = Statement.fromSession(this.session, sql, description.cols, this.execLock);
if (this.defaultSafeIntegerMode) {
stmt.safeIntegers(true);
}
return stmt;
}View on GitHub (pinned to bad083fafb)
Solutions
- Call await db.reconnect() to reopen the same Connection object, then retry prepare()
- Create a new Connection via connect(config) instead of reusing the closed one
- Remove Connection objects from your pool/registry when you close them so they are never handed out again
- Ensure close() only runs after all users of the connection are finished
Example fix
// before
await db.close();
const stmt = await db.prepare('SELECT * FROM users WHERE id = ?');
// TypeError: The database connection is not open
// after
if (connectionWasClosed) {
await db.reconnect();
}
const stmt = await db.prepare('SELECT * FROM users WHERE id = ?'); Defensive patterns
Strategy: try-catch
Validate before calling
// Connection exposes no public isOpen getter — track lifecycle at the call site.
let db = connect(config);
let dbOpen = true;
async function closeDb() {
await db.close();
dbOpen = false;
}
async function prepareSafe(sql: string) {
if (!dbOpen) {
await db.reconnect();
dbOpen = true;
}
return db.prepare(sql);
} Try / catch
try {
return await db.prepare(sql);
} catch (e) {
if (e instanceof TypeError && e.message.includes('not open')) {
await db.reconnect();
return db.prepare(sql);
}
throw e;
} Prevention
- Wrap close() in a helper that also removes the Connection from any pool or registry
- Use await db.reconnect() to reopen rather than reusing a closed object implicitly
- Apply pragmas and prepare statements right after connect so lifecycle is linear
- In pools, hand out only connections you have not marked closed
When it happens
Trigger: await db.close(); await db.prepare(sql). Reusing a pooled Connection object after a maintenance path closed it. An error path closing the connection, then normal flow continuing to prepare statements.
Common situations: Connection pools that close idle connections but hand them out again; retry logic that closes on a network error and later prepares; long-lived server code where a shutdown hook closed the connection before late requests arrive.
Related errors
- Database is closed
- CLIENT_CLOSED
- TRANSACTION_CLOSED
- Cannot operate on a closed cursor
- Cannot operate on a closed connection
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/b6cd5e5be17df387.
Report an issue: GitHub.