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

  1. Call and await `db.connect()` once before any query/exec — keep the promise and reuse it everywhere (`dbReady` pattern)
  2. If connect() failed, handle that error; do not continue issuing queries on the same instance without reconnecting
  3. 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

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


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/4d725f8bb45f05c4. Report an issue: GitHub.