{"record":{"id":"acd43acf9b0ec060","repo":"thedotmack/claude-mem","slug":"sync-hub-push-checkpoint-order-requires-head-seq","errorCode":null,"errorMessage":"sync hub push: checkpoint order requires head_seq <= projected_seq","messagePattern":"sync hub push: checkpoint order requires head_seq <= projected_seq","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":1070,"sourceCode":"      }\n      seqTuple.set(ack.seq, key);\n    }\n\n    for (const [key, expected] of sentCounts) {\n      const actual = ackCounts.get(key) ?? 0;\n      if (actual !== expected) {\n        throw new Error(\n          `sync hub push: 200 response acknowledgment multiplicity mismatch (expected ${expected}, received ${actual})`\n        );\n      }\n    }\n    if (ackCounts.size !== sentCounts.size) {\n      // Defensive: the unknown-tuple branch above should make this impossible.\n      throw new Error('sync hub push: 200 response acknowledgment multiset mismatch');\n    }\n\n    if (compareCanonicalDecimals(response.head_seq, response.projected_seq) > 0) {\n      throw new Error('sync hub push: checkpoint order requires head_seq <= projected_seq');\n    }\n    for (const ack of response.acked) {\n      if (compareCanonicalDecimals(ack.seq, response.head_seq) > 0) {\n        throw new Error('sync hub push: acknowledgment seq exceeds head_seq');\n      }\n      if (compareCanonicalDecimals(ack.seq, response.projected_seq) > 0) {\n        throw new Error('sync hub push: sent operation is not covered by projected_seq');\n      }\n    }\n  }\n\n  /**\n   * Stamp rows / delete outbox entries for a fully validated acknowledgment\n   * multiset. The hub may return entries in any order.\n   */\n  private stampAcked(acked: AckedOp[], pushed: WireOp[]): void {\n    const now = Date.now();\n    const bodies = new Map(pushed.map(op => {","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L1052-L1088","documentation":"Thrown when the hub returns head_seq greater than projected_seq, violating the checkpoint ordering invariant. head_seq is the durable replicated head; projected_seq is the projected/optimistic sequence. The contract requires head_seq <= projected_seq, so head beyond projected is an inconsistent hub checkpoint.","triggerScenarios":"validatePushResponse runs compareCanonicalDecimals(response.head_seq, response.projected_seq); a positive result (head_seq > projected_seq) throws. Both values were already validated as canonical decimal strings upstream.","commonSituations":"Hub bug where the projected pointer lags the durable head (e.g. projected_seq not advanced after a commit), a hub rolling back projected but not head, or version skew redefining what head/projected mean. The client refuses a checkpoint that cannot be linearized.","solutions":["Inspect the hub's head_seq and projected_seq values for the device/user; head must never exceed projected.","Fix the hub checkpoint advancement so projected_seq is always >= head_seq at response time.","Retry the push after the hub corrects the pointers; do not advance the local cursor on a violating checkpoint.","Check hub logs for a projected_seq update that failed after head_seq moved."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await cloudSync.push(pushed); }\ncatch (e) {\n  if (e instanceof Error && e.message.includes('checkpoint order requires head_seq <= projected_seq')) {\n    logger.error('SYNC', e.message); // hub checkpoint inconsistency\n    await scheduleRetry(); return;\n  }\n  throw e;\n}","preventionTips":["Monitor hub head_seq/projected_seq; head must never exceed projected.","Do not advance the local cursor when this fires — the checkpoint is not linearizable.","Retry after confirming the hub has corrected the pointer ordering."],"tags":["sync","cloud-sync","hub-response","validation","checkpoint"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}