{"record":{"id":"eb84ae8334d95a79","repo":"thedotmack/claude-mem","slug":"sync-hub-push-sent-operation-is-not-covered-by-pr","errorCode":null,"errorMessage":"sync hub push: sent operation is not covered by projected_seq","messagePattern":"sync hub push: sent operation is not covered by projected_seq","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":1077,"sourceCode":"        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 => {\n      const body = parseCanonicalOperation(op);\n      return [operationTupleKey({\n        id: body.id,\n        kind: body.kind,\n        entity_rev: body.entity_rev,\n        operation_sha256: op.operation_sha256,\n      }), { body, operationSha256: op.operation_sha256 }] as const;","sourceCodeStart":1059,"sourceCodeEnd":1095,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L1059-L1095","documentation":"Thrown when an acked operation's seq exceeds projected_seq. projected_seq must cover every sent operation; an ack seq beyond projected means the hub acknowledged an operation not yet reflected in its projection — the push is not fully accounted for.","triggerScenarios":"validatePushResponse, for each ack, compareCanonicalDecimals(ack.seq, response.projected_seq) > 0 throws. Runs after [128] (seq <= head_seq) — since head_seq <= projected_seq was already enforced [127], this is an additional coverage guarantee on the projection pointer specifically.","commonSituations":"Hub advanced head but lagged projected_seq, projected_seq computed from a stale read, or hub bug where the projection pointer wasn't refreshed after sequencing the batch. Client refuses because it cannot confirm the projection includes the pushed ops.","solutions":["Find the ack with seq > projected_seq and confirm projected_seq is stale relative to the acked batch.","On the hub, recompute projected_seq after sequencing so it covers all returned acks.","Retry the push once the hub projection catches up.","Verify the hub is not returning a cached/projected value computed before the write committed."],"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('not covered by projected_seq')) {\n    logger.error('SYNC', e.message); // projection lagged behind acks\n    await scheduleRetry(); return;\n  }\n  throw e;\n}","preventionTips":["Require the hub to recompute projected_seq after sequencing so it covers all acks.","Treat a persistent projection lag as a hub bug, not transient.","Retry only after confirming projected_seq has caught up."],"tags":["sync","cloud-sync","hub-response","validation","checkpoint","sequence-integrity"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}