{"record":{"id":"070438c0c6b2bab0","repo":"thedotmack/claude-mem","slug":"sync-hub-epoch-changed-cursor-reset-full-re-pul","errorCode":null,"errorMessage":"Sync hub epoch changed — cursor reset, full re-pull required, eligible native revisions requeued","messagePattern":"Sync hub epoch changed — cursor reset, full re-pull required, eligible native revisions requeued","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/sync/SyncApply.ts","lineNumber":404,"sourceCode":"                SELECT 1\n                FROM sync_launch_exclusions AS launch\n                WHERE launch.kind = ?\n                  AND launch.origin_local_id = CAST(${table}.id AS TEXT)\n                  AND (\n                    LENGTH(launch.through_rev) > LENGTH(CAST(${table}.sync_rev AS TEXT))\n                    OR (\n                      LENGTH(launch.through_rev) = LENGTH(CAST(${table}.sync_rev AS TEXT))\n                      AND launch.through_rev >= CAST(${table}.sync_rev AS TEXT)\n                    )\n                  )\n              )\n          `).run(kind).changes;\n        }\n      }\n    });\n    tx();\n    if (stored !== null) {\n      logger.warn('SYNC_APPLY', 'Sync hub epoch changed — cursor reset, full re-pull required, eligible native revisions requeued', {\n        oldEpoch: stored,\n        newEpoch: epoch,\n        requeued,\n      });\n      return true;\n    }\n    logger.info('SYNC_APPLY', 'Adopted initial sync hub epoch', { epoch });\n    return false;\n  }\n\n  // -------------------------------------------------------------------------\n  // applyOps\n  // -------------------------------------------------------------------------\n\n  /**\n   * Apply one pulled batch. Ops must be in ascending seq order (the hub\n   * returns them that way). Runs in ONE transaction: row upserts, mutation\n   * UPDATEs, and the cursor advance commit together or roll back together.","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/services/sync/SyncApply.ts#L386-L422","documentation":"applyEpoch stores the sync hub's epoch. When an incoming epoch differs from a previously stored one, a single transaction resets the pull cursor, forces a full re-pull, and requeues eligible native revisions; this warning reports the old/new epoch and requeued count. Adopting a first-ever epoch is an info log, not this warning.","triggerScenarios":"The sync hub was reset or redeployed with a new epoch while this device had an older stored epoch (stored !== null and stored !== epoch).","commonSituations":"Hub disaster recovery, hub migration, or a device coming back online after a hub reset.","solutions":["No manual action — the full re-pull repopulates local state; expect the first sync to take longer.","Keep the app running until the re-pull completes.","If the warning repeats continuously, report epoch flapping to the hub operator."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Expect a heavier first sync after hub maintenance windows.","Do not wipe local data on an epoch change — the full re-pull is by design."],"tags":["sync","epoch","cursor-reset","full-repull"],"backgroundTag":"sync-epoch-mismatch","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}