tursodatabase/turso · error · Error
Database not connected. Call connect() first.
Error message
Database not connected. Call connect() first.
What it means
Second branch of checkOpen(): _closed is false but _connected or _connection is unset. The constructor only stores options; the native database, connection, and sync bootstrap all happen inside connect(). Until `await db.connect()` resolves, the Database is a shell and any statement-level call throws this.
Solutions
- Always `await db.connect()` before any query, ideally once in a dedicated init module that exports a ready promise
- If connect() can fail, surface and fix that error first — this message is just the downstream symptom
- Guard entry points with `db.open` (true only when connected and not closed)
- Initialize the Database lazily: export `getDb()` that connects on first call and caches the promise
Example fix
// before
const db = new Database({ path: getDbPath('app.db') });
db.connect(); // missing await
const row = await db.get('SELECT 1'); // throws 'Database not connected...'
// after
const db = new Database({ path: getDbPath('app.db') });
const ready = db.connect();
await ready;
const row = await db.get('SELECT 1'); Defensive patterns
Strategy: validation
Validate before calling
const ready = db.connect(); // once, at startup
// ...
await ready; // every consumer awaits this before querying
await db.get('SELECT 1'); Type guard
function isConnected(db: Database): boolean {
return db.open; // !_closed && _connection !== null
} Try / catch
try {
await db.get(sql, params);
} catch (e) {
if (e instanceof Error && e.message.includes('Call connect() first')) {
await db.connect();
return db.get(sql, params);
}
throw e;
} Prevention
- Export a single ready promise (or lazily-connecting getDb()) from your db module and await it everywhere
- Always await connect(); treat a failed connect() as a hard startup error instead of swallowing it
- Gate early render/effects on a connected flag so queries never fire first
When it happens
Trigger: Calling db.prepare/exec/all/run/get immediately after `new Database(...)` without awaiting connect(); calling them from code that runs before an async init routine finishes (e.g. render firing before the connect() promise resolves); connect() rejected and the error swallowed, leaving callers to hit this on the next use.
Common situations: Forgetting the await on connect() in app bootstrap; React component effects querying before a `ready` flag is set; connect() failing (bad path, native error) inside a try that logs but continues, after which every query fails with this message instead of the original error.
Related errors
- Database is closed
- jsContextPointer == 0
- No connection available
- Statement has been finalized
- The transaction has already completed
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/4d725f8bb45f05c4.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/react-native/src/Database.ts:483
/**
* Get last insert rowid
*/
get lastInsertRowid(): number {
if (!this._connection) {
return 0;
}
return this._connection.lastInsertRowid();
}
/**
* Check if open and throw if not
*/
private checkOpen(): void {
if (this._closed) {
throw new Error('Database is closed');
}
if (!this._connected || !this._connection) {
throw new Error('Database not connected. Call connect() first.');
}
}
}
View on GitHub (pinned to 244cde92a7)