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 by driving the native sync database's stats() operation; it requires the full sync setup (_isSync, _nativeSyncDb, _ioContext). On a local-only database these handles were never created, so the metrics the method reports (sync frame/transfer statistics) do not exist and the call is rejected.

Solutions

  1. Configure the database for sync (url + authToken options) and await connect() before calling stats()
  2. Guard diagnostics UI with `db.isSync` and hide/disable stats for local-only databases
  3. Centralize the Database construction so every caller gets the same sync/local configuration

Example fix

// before
async function showSyncStats(db) {
  const stats = await db.stats(); // throws on local-only db
}

// after
async function showSyncStats(db) {
  if (!db.isSync) return null;
  return await db.stats();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!db.isSync) {
  return null; // stats only exist for sync databases
}
return await db.stats();

Type guard

function isSyncDb(db: Database): boolean {
  return db.isSync;
}

Try / catch

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

Prevention

When it happens

Trigger: Calling await db.stats() on a Database constructed with only `{ path }`, or before `await db.connect()` completed on a sync database. Any of the three guard conditions missing triggers it.

Common situations: A diagnostics/debug screen that calls stats() unconditionally while the app supports a local-only mode; monitoring code written against a sync dev environment then shipped to a build where url is not configured.

Related errors


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

Appendix: 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 244cde92a7)