tursodatabase/turso · error · Error
Database not connected. Call connect() first.
Error message
Database not connected. Call connect() first.
What it means
checkOpen() throws 'Database not connected. Call connect() first.' when the database is not closed but _connected or _connection is false. The constructor deliberately does no I/O; connect() is what opens the local database or bootstraps the sync one, and it sets _connected = true only after init succeeds. So this error means either connect() was never awaited, or a previous connect() failed and left the instance half-initialized.
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 bad083fafb)
Solutions
- Call and await `db.connect()` once before any query/exec — keep the promise and reuse it everywhere (`dbReady` pattern)
- If connect() failed, handle that error; do not continue issuing queries on the same instance without reconnecting
- Wrap the instance in a small manager that lazily connects and gates every operation on readiness
Example fix
// before
const db = new Database({ path: 'app.db' });
await db.query('SELECT * FROM users'); // throws: not connected
// after
const db = new Database({ path: 'app.db' });
await db.connect();
await db.query('SELECT * FROM users'); Defensive patterns
Strategy: validation
Validate before calling
// Gate every operation on one shared connect promise
let db: Database;
let ready: Promise<void>;
function openDb(opts: DatabaseOpts) {
db = new Database(opts);
ready = db.connect().catch((e) => { ready = Promise.reject(e); throw e; });
return ready;
}
await ready; // before ANY query/exec
await db.query('SELECT 1'); Try / catch
try { await db.query(sql); } catch (e) { if (e instanceof Error && /Call connect\(\) first/.test(e.message)) { await db.connect(); return db.query(sql); } throw e; } Prevention
- The constructor does not open anything — connect() is mandatory, await it before first use
- Reuse a single connect promise app-wide instead of calling connect() from many places
- Never swallow connect() errors; a failed connect leaves the instance unusable
When it happens
Trigger: Constructing `new Database(opts)` and immediately calling `db.query(...)` without `await db.connect()`; fire-and-forget connect() racing the first query; connect() throwing (e.g., native module missing, bad path) and later calls proceeding anyway.
Common situations: Forgetting the connect step when porting from a binding that opens eagerly; startup races in useEffect or init code; swallowing the connect() error with an empty catch and continuing; hot reload creating a new instance whose connect promise was lost.
Related errors
- push() is only available for sync databases
- pull() is only available for sync databases
- stats() is only available for sync databases
- Database is closed
- Turso native module not loaded
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/4d725f8bb45f05c4.
Report an issue: GitHub.