{"record":{"id":"77fd47a699efdd7a","repo":"thedotmack/claude-mem","slug":"sync-hub-push-duplicate-operation-tuple-claimed-d","errorCode":null,"errorMessage":"sync hub push: duplicate operation tuple claimed different sequences","messagePattern":"sync hub push: duplicate operation tuple claimed different sequences","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":1045,"sourceCode":"        entity_rev: body.entity_rev,\n        operation_sha256: op.operation_sha256,\n      });\n      sentCounts.set(key, (sentCounts.get(key) ?? 0) + 1);\n    }\n\n    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    }","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/services/sync/CloudSync.ts#L1027-L1063","documentation":"The same (id, kind, entity_rev, operation_sha256) tuple appears more than once in the acked array but each occurrence claims a different seq — the hub assigned two different log positions to one operation. A tuple maps to exactly one sequence by construction. Caught in validatePushResponse before stamping; flush() backs off and retries. Persistent occurrences point to a hub append/dedupe bug (e.g. the (origin_device, kind, origin_id, rev) dedupe failing under retries).","triggerScenarios":"Client retries a timed-out POST and the hub appends twice because its dedupe key is broken, then acks both positions; a hub race between duplicate submit handlers; replica divergence merging the same op at two seqs.","commonSituations":"Hub dedupe index missing/partial after a schema migration; retry storms during network flaps exposing a hub race; multi-region hub with non-atomic log merge.","solutions":["Reproduce with a duplicate POST of the same op body and inspect how many acks/seqs the hub returns","On the hub, make the (origin_device, kind, origin_id, rev) dedupe atomic with the append (unique constraint or transactional check)","If duplicate log entries already exist, compact/repair the hub log before clients can converge","Until fixed, expect the client to safely reject and retry — no local corruption occurs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if (/duplicate operation tuple claimed different sequences/.test(sync.status().lastError ?? '')) {\n  // hub assigned two log positions to one op: test duplicate POST idempotency\n  // against the hub, fix its dedupe, then let client retries converge\n}","preventionTips":["Give the hub an atomic unique constraint on (origin_device, kind, origin_id, rev) covering appends","Load-test the hub with duplicate concurrent submissions of the same op","Treat any occurrence as a hub bug — the client can only safely reject and retry"],"tags":["sync","hub","integrity","ack","duplicate","invariant"],"backgroundTag":"data-integrity-violation","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}