tursodatabase/turso · error · Error
push() is only available for sync databases
Error message
push() is only available for sync databases
What it means
push() on the React Native Database uploads local changes through the native sync database object. The guard requires three things that only exist on a connected sync database: _isSync (set in the constructor when opts.url is non-null), _nativeSyncDb, and _ioContext (both created during connect() in sync mode). If the database is local-only, or sync mode was configured but connect() has not completed, the call throws.
Source
Thrown at bindings/react-native/src/Database.ts:348
async transaction<T>(fn: () => T | Promise<T>): Promise<T> {
this.checkOpen();
await this.exec('BEGIN');
try {
const result = await fn();
await this.exec('COMMIT');
return result;
} catch (error) {
await this.exec('ROLLBACK');
throw error;
}
}
/**
* Push local changes to remote (sync databases only)
*/
async push(): Promise<void> {
if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {
throw new Error('push() is only available for sync databases');
}
const operation = this._nativeSyncDb.pushChanges();
await driveVoidOperation(operation, this._nativeSyncDb, this._ioContext);
}
/**
* Pull remote changes and apply locally (sync databases only)
*
* @returns true if changes were applied, false if no changes
*/
async pull(): Promise<boolean> {
if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {
throw new Error('pull() is only available for sync databases');
}
// Wait for changes
const waitOperation = this._nativeSyncDb.waitChanges();View on GitHub (pinned to bad083fafb)
Solutions
- Pass `url` (and `authToken`) to the Database constructor so it is created in sync mode
- Always `await db.connect()` before any push/pull/stats/checkpoint call
- Guard the call site: keep a typed 'synced database' wrapper so push() is unreachable for local handles
Example fix
// before
const db = new Database({ path: 'app.db' }); // no url -> local mode
await db.push(); // throws
// after
const db = new Database({ path: 'app.db', url, authToken });
await db.connect();
await db.push(); Defensive patterns
Strategy: validation
Validate before calling
// Mode is decided by url presence in the constructor opts — check it, and gate on connect()
function isSyncConfig(opts: DatabaseOpts): boolean {
return opts.url !== undefined && opts.url !== null;
}
if (isSyncConfig(opts)) {
await db.connect(); // creates _nativeSyncDb + _ioContext
await db.push();
} Try / catch
try { await db.push(); } catch (e) { if (e instanceof Error && e.message.includes('only available for sync databases')) { /* wrong mode or not connected: fix config/lifecycle */ } throw e; } Prevention
- Await connect() once and share that promise; never let sync calls race it
- Only enable push in app flavors where url is configured
- After a failed connect(), reconnect before retrying push
When it happens
Trigger: `new Database({ path: 'app.db' })` with no url followed by `await db.push()`; constructing with url but calling push() before `await db.connect()` finishes; a sync-call helper invoked on a database whose connect() failed earlier (leaving _nativeSyncDb null).
Common situations: Adding sync calls to an app first built as local-only; race conditions at app startup where sync runs before connect resolves; code shared between local and synced screens; error paths where connect() threw and later code still attempts to push.
Related errors
- pull() is only available for sync databases
- stats() is only available for sync databases
- checkpoint() is only available for sync databases
- HTTP request missing URL: no URL in request and no baseUrl i
- remoteWritesExperimental requires a non-null URL
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/f21b4c22ec341e15.
Report an issue: GitHub.