{"record":{"id":"ecd59123cbb04776","repo":"thedotmack/claude-mem","slug":"cloud-sync-ack-conflict-for-body-id-rev-body","errorCode":null,"errorMessage":"cloud sync ack conflict for ${body.id} rev ${body.entity_rev}","messagePattern":"cloud sync ack conflict for (.+?) rev (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/services/sync/CloudSync.ts","lineNumber":1137,"sourceCode":"        this.reconcileAckedContent(body, pushedOp.operationSha256, now);\n      }\n    });\n    tx();\n  }\n\n  private advanceEntityHead(\n    body: ReturnType<typeof parseCanonicalOperation>,\n    operationSha256: string,\n    now: number,\n  ): void {\n    const current = this.db.prepare(`\n      SELECT entity_rev, operation_sha256 FROM sync_entity_heads WHERE entity_id = ?\n    `).get(body.id) as { entity_rev: string; operation_sha256: string } | undefined;\n    if (current) {\n      const order = compareCanonicalDecimals(body.entity_rev, current.entity_rev);\n      if (order < 0) return;\n      if (order === 0 && current.operation_sha256 !== operationSha256) {\n        throw new Error(`cloud sync ack conflict for ${body.id} rev ${body.entity_rev}`);\n      }\n    }\n    this.db.prepare(`\n      INSERT INTO sync_entity_heads\n        (entity_id, kind, origin_device_id, origin_local_id, entity_rev,\n         operation_sha256, deleted, updated_at_epoch)\n      VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n      ON CONFLICT(entity_id) DO UPDATE SET\n        entity_rev=excluded.entity_rev,\n        operation_sha256=excluded.operation_sha256,\n        deleted=excluded.deleted,\n        updated_at_epoch=excluded.updated_at_epoch\n    `).run(\n      body.id, body.kind, body.origin_device_id, body.origin_local_id,\n      body.entity_rev, operationSha256, body.deleted ? 1 : 0, now,\n    );\n  }\n","sourceCodeStart":1119,"sourceCodeEnd":1155,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L1119-L1155","documentation":"Thrown in advanceEntityHead during stampAcked when an entity already has a row in sync_entity_heads with the SAME entity_rev but a DIFFERENT operation_sha256. entity_rev is meant to be content-addressed: the same rev for the same entity must hash to the same operation. A divergence means two distinct operations claim the same revision — a genuine content conflict or a hash collision.","triggerScenarios":"stampAcked -> advanceEntityHead: SELECT finds an existing head with current.entity_rev === body.entity_rev but current.operation_sha256 !== operationSha256. compareCanonicalDecimals returns 0 (equal rev) but the hashes differ, so it throws rather than silently overwriting.","commonSituations":"Two devices produced different operation content that hashed differently but were assigned the same entity_rev by the hub, an operation_sha256 recomputed differently between push and ack (encoding/casing), or a real hash collision (astronomically rare). Can also follow a partial/buggy remap of the outbox. Indicates data divergence that must be investigated, not auto-resolved.","solutions":["Inspect sync_entity_heads for body.id: compare stored operation_sha256 vs the acked operation_sha256 — a real divergence shows two different ops at one rev.","If the hashes differ due to encoding/casing normalization, fix the producer to emit canonical operation_sha256 consistently.","If it is genuine divergence, resolve manually (pick the authoritative op, bump entity_rev) — do not let stampAcked silently overwrite.","Run remap-outbox or a reseed to reconcile divergent entity heads after deciding the canonical op."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before pushing, confirm local entity heads agree with the op hashes you push:\nfunction checkHeadConsistency(db: Database, id: string, entityRev: string, opSha: string): void {\n  const row = db.prepare('SELECT operation_sha256 FROM sync_entity_heads WHERE entity_id=?').get(id) as { operation_sha256?: string } | undefined;\n  if (row && compareCanonicalDecimals(entityRev, /* current rev */ row.operation_sha256) === 0\n      && row.operation_sha256 !== opSha) {\n    throw new Error('pre-push: head hash divergence for ' + id);\n  }\n}","typeGuard":null,"tryCatchPattern":"try { await cloudSync.push(pushed); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('cloud sync ack conflict for')) {\n    // content-addressed divergence — needs human resolution, do not auto-overwrite\n    logger.error('SYNC', e.message); await alertOperator(e.message); return;\n  }\n  throw e;\n}","preventionTips":["Produce operation_sha256 from canonical-encoded payloads so the same rev always hashes identically.","Never let two devices claim the same entity_rev for different content; coordinate rev allocation via the hub.","Run remap-outbox after schema/migration changes to keep entity heads consistent."],"tags":["sync","cloud-sync","data-integrity","conflict","content-addressed"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}