{"record":{"id":"e3b2d6c2a1416065","repo":"tursodatabase/turso","slug":"pull-is-only-available-for-sync-databases","errorCode":null,"errorMessage":"pull() is only available for sync databases","messagePattern":"pull\\(\\) is only available for sync databases","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/react-native/src/Database.ts","lineNumber":362,"sourceCode":"   * Push local changes to remote (sync databases only)\n   */\n  async push(): Promise<void> {\n    if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {\n      throw new Error('push() is only available for sync databases');\n    }\n\n    const operation = this._nativeSyncDb.pushChanges();\n    await driveVoidOperation(operation, this._nativeSyncDb, this._ioContext);\n  }\n\n  /**\n   * Pull remote changes and apply locally (sync databases only)\n   *\n   * @returns true if changes were applied, false if no changes\n   */\n  async pull(): Promise<boolean> {\n    if (!this._isSync || !this._nativeSyncDb || !this._ioContext) {\n      throw new Error('pull() is only available for sync databases');\n    }\n\n    // Wait for changes\n    const waitOperation = this._nativeSyncDb.waitChanges();\n    const changes = await driveChangesOperation(waitOperation, this._nativeSyncDb, this._ioContext);\n\n    // If no changes, return false\n    if (!changes) {\n      return false;\n    }\n\n    // Apply changes\n    const applyOperation = this._nativeSyncDb.applyChanges(changes);\n    await driveVoidOperation(applyOperation, this._nativeSyncDb, this._ioContext);\n\n    return true;\n  }\n","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/react-native/src/Database.ts#L344-L380","documentation":"pull() on the React Native Database waits for remote changes (waitChanges) and applies them locally, using the native sync database and IO context created during a sync-mode connect(). The guard `!this._isSync || !this._nativeSyncDb || !this._ioContext` throws when the database is local-only (no url in opts) or when connect() has not yet created the native sync objects. Like the other sync methods, it is a mode/lifecycle error rather than a network error.","triggerScenarios":"`new Database({ path })` without url then `await db.pull()`; calling pull() in a startup effect before `await db.connect()` resolves; retrying pull() after a failed connect() without reconnecting.","commonSituations":"Offline-first flows wired up before sync configuration was added; useEffect-based sync loops racing the initial connect; navigation to a screen that pulls on mount while the DB singleton is still connecting.","solutions":["Construct the Database with `url` (and `authToken`) so isSyncConfig() is true and connect() builds the native sync database","Await connect() — and reuse its promise — before starting any pull loop","If connect() fails, surface the error and re-run connect() before attempting pull() again"],"exampleFix":"// before\nconst db = new Database({ path: 'app.db' });\nuseEffect(() => { db.pull(); }, []); // throws: local mode\n\n// after\nconst db = new Database({ path: 'app.db', url, authToken });\nawait db.connect();\nuseEffect(() => { db.pull(); }, []);","handlingStrategy":"validation","validationCode":"// Reusable lazy-connect gate for sync operations\nlet connectPromise: Promise<void> | null = null;\nfunction ensureConnected(db: Database): Promise<void> {\n  return (connectPromise ??= db.connect());\n}\n\nif (isSyncConfig(opts)) {\n  await ensureConnected(db);\n  const changed = await db.pull();\n}","typeGuard":null,"tryCatchPattern":"try { await db.pull(); } catch (e) { if (e instanceof Error && e.message.includes('only available for sync databases')) { await db.connect(); return db.pull(); } throw e; }","preventionTips":["Start pull loops only after connect() resolves","Construct with url — pull() cannot be enabled post-hoc","Handle connect() errors explicitly so half-initialized instances are not reused"],"tags":["react-native","sync","pull","configuration","lifecycle"],"backgroundTag":"feature-not-enabled","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}