tursodatabase/turso · error · Error

stats() is only available for sync databases

Error message

stats() is only available for sync databases

What it means

stats() returns SyncStats from the native sync database (driven through driveStatsOperation with the IO context). It is only meaningful for sync databases, and the guard throws unless the constructor saw a url AND connect() successfully created _nativeSyncDb and _ioContext. On a local-only database there are no sync statistics to report.

Source

Thrown at bindings/react-native/src/Database.ts:388

    if (!changes) {
      return false;
    }

    // Apply changes
    const applyOperation = this._nativeSyncDb.applyChanges(changes);
    await driveVoidOperation(applyOperation, this._nativeSyncDb, this._ioContext);

    return true;
  }

  /**
   * Get sync statistics (sync databases only)
   *
   * @returns Sync stats
   */
  async stats(): Promise<SyncStats> {
    if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {
      throw new Error('stats() is only available for sync databases');
    }

    const operation = this._nativeSyncDb.stats();
    return driveStatsOperation(operation, this._nativeSyncDb, this._ioContext);
  }

  /**
   * Checkpoint database (sync databases only)
   */
  async checkpoint(): Promise<void> {
    if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {
      throw new Error('checkpoint() is only available for sync databases');
    }

    const operation = this._nativeSyncDb.checkpoint();
    await driveVoidOperation(operation, this._nativeSyncDb, this._ioContext);
  }

View on GitHub (pinned to bad083fafb)

Solutions

  1. Open the database in sync mode by passing `url` and `authToken` in the constructor options
  2. Ensure `await db.connect()` succeeded before requesting stats
  3. Gate the dashboard/telemetry call behind the same flag that decides sync mode

Example fix

// before
const db = new Database({ path: 'app.db' });
const s = await db.stats(); // throws

// after
const db = new Database({ path: 'app.db', url, authToken });
await db.connect();
const s = await db.stats();
Defensive patterns

Strategy: validation

Validate before calling

const isSyncConfig = (o: DatabaseOpts) => o.url != null;

async function syncStats(db: Database, o: DatabaseOpts): Promise<SyncStats | null> {
  if (!isSyncConfig(o)) return null;
  await db.connect();
  return db.stats();
}

Try / catch

try { return await db.stats(); } catch (e) { if (e instanceof Error && e.message.includes('only available for sync databases')) return null; throw e; }

Prevention

When it happens

Trigger: `new Database({ path })` without url followed by `await db.stats()`; a debug/telemetry panel calling stats() on a database whose connect() has not run or failed; sharing analytics code across local and synced app flavors.

Common situations: Adding a sync-health dashboard to an app that still opens the database locally; telemetry initialized before connection completes; build flavors where only one has the url configured.

Related errors


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