{"record":{"id":"d9657f0c6c43a206","repo":"thedotmack/claude-mem","slug":"sync-hub-push-distinct-operation-tuples-claimed-t","errorCode":null,"errorMessage":"sync hub push: distinct operation tuples claimed the same sequence","messagePattern":"sync hub push: distinct operation tuples claimed the same sequence","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":1051,"sourceCode":"    const ackCounts = new Map<string, number>();\n    const tupleSeq = new Map<string, string>();\n    const seqTuple = new Map<string, string>();\n    for (const ack of response.acked) {\n      const key = operationTupleKey(ack);\n      if (!sentCounts.has(key)) {\n        throw new Error('sync hub push: 200 response contains an extra or mismatched acknowledgment tuple');\n      }\n      ackCounts.set(key, (ackCounts.get(key) ?? 0) + 1);\n\n      const priorTupleSeq = tupleSeq.get(key);\n      if (priorTupleSeq !== undefined && priorTupleSeq !== ack.seq) {\n        throw new Error('sync hub push: duplicate operation tuple claimed different sequences');\n      }\n      tupleSeq.set(key, ack.seq);\n\n      const priorSeqTuple = seqTuple.get(ack.seq);\n      if (priorSeqTuple !== undefined && priorSeqTuple !== key) {\n        throw new Error('sync hub push: distinct operation tuples claimed the same sequence');\n      }\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) {","sourceCodeStart":1033,"sourceCodeEnd":1069,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L1033-L1069","documentation":"Thrown when two DISTINCT operation tuples (different operationTupleKey) are assigned the SAME `seq` by the hub. Each sequence number must belong to exactly one operation; a collision means the hub's sequencer is broken. Detected via the inverse seqTuple map (seq -> tuple).","triggerScenarios":"A 200 push response where two acked entries have different (id, kind, entity_rev, operation_sha256) but identical `seq`. The first sets seqTuple[seq]=keyA; the second with a different key but same seq triggers the throw.","commonSituations":"Hub sequencer race/duplicate allocation, sequence reuse after a rollback, or a hub that sequences by a non-unique attribute. Pure hub-side integrity violation; the client correctly refuses to apply an ambiguous ordering.","solutions":["Find the two acked entries sharing one seq but differing in tuple — that seq is the hub collision point.","Fix the hub sequencer so seq allocation is unique and monotonic.","Do not apply this batch; retry once the hub is corrected, since applying would corrupt local ordering.","Inspect hub logs around the colliding seq for concurrent allocation."],"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('distinct operation tuples claimed the same sequence')) {\n    logger.error('SYNC', e.message); // hub seq collision; escalate\n    return;\n  }\n  throw e;\n}","preventionTips":["Monitor hub responses for seq collisions; this indicates a sequencer allocation bug.","Keep the client strict (do not relax this check) — applying colliding seqs corrupts local order.","Attach the colliding seq and both tuples to incident reports."],"tags":["sync","cloud-sync","hub-response","validation","sequence-integrity"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}