{"record":{"id":"5ca9f413815e8505","repo":"ruvnet/ruflo","slug":"concurrent-write-detected-on-aggregate-aggregat","errorCode":null,"errorMessage":"Concurrent write detected on aggregate '${aggregateId}'. Resolve via contest mechanism.","messagePattern":"Concurrent write detected on aggregate '(.+?)'\\. Resolve via contest mechanism\\.","errorType":"exception","errorClass":"ConcurrentWriteError","httpStatus":null,"severity":"critical","filePath":"v3/@claude-flow/claims/src/infrastructure/federated-event-store.ts","lineNumber":226,"sourceCode":"   * Apply an event received from a federation peer.\n   * Throws `ConcurrentWriteError` if the remote event is concurrent with our\n   * latest known state for the aggregate; the caller should surface this as\n   * a contest.\n   */\n  async applyRemoteEvent(\n    event: ClaimDomainEvent,\n    remoteVclock: VectorClock,\n    remoteHlc: HlcTimestamp,\n    envelopeSignature?: string,\n  ): Promise<void> {\n    const state = this.aggregates.get(event.aggregateId) ?? {\n      vclock: zeroVectorClock(),\n    };\n\n    // Concurrency check\n    const order = compareVectorClocks(state.vclock, remoteVclock);\n    if (order === 'concurrent') {\n      throw new ConcurrentWriteError(event.aggregateId, state.vclock, remoteVclock);\n    }\n    if (order === 'after' || order === 'equal') {\n      // We've already seen this or a later event — drop silently (idempotent).\n      return;\n    }\n\n    // Update our HLC from the remote (may throw HlcSkewError).\n    const mergedHlc = this.hlc.update(remoteHlc);\n    const mergedVclock = mergeVectorClocks(state.vclock, remoteVclock);\n\n    const stamped = writeFederationMetadata(event, {\n      hlc: mergedHlc,\n      vclock: mergedVclock,\n      originNodeId: readFederationMetadata(event)?.originNodeId ?? 'unknown',\n      arrivedFromFederation: true,\n      envelopeSignature,\n    });\n","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/claims/src/infrastructure/federated-event-store.ts#L208-L244","documentation":"FederatedEventStore.applyRemoteEvent compares the remote event's vector clock against the local vclock for the aggregate; when compareVectorClocks returns 'concurrent' (neither dominates), both nodes wrote events independently and the store refuses to silently pick a winner. It throws the typed ConcurrentWriteError and expects the conflict to be settled out-of-band through the claims contest mechanism (contestSteal/resolveContest).","triggerScenarios":"Two nodes apply events to the same claim aggregate without syncing first — both steal or mutate the same issue during a network partition, or a node replays buffered outbound events after reconnect while the peer already advanced the aggregate.","commonSituations":"Multi-writer topologies without per-aggregate ownership or a lease; partition healing; restarting a node from an old snapshot while others progressed; test harnesses driving two stores with the same events in different orders.","solutions":["Catch ConcurrentWriteError and route the aggregate into the contest workflow: let contestSteal/resolveContest pick the winner, then re-apply","Serialize writes per aggregate: only the current claim owner (or lease holder) emits events; everyone else syncs read-only","Before a rejoined node writes again, replay/sync bidirectionally so one vclock dominates","Deduplicate identical events before applying so re-delivery never produces concurrent clocks"],"exampleFix":"// before\nawait store.applyRemoteEvent(ev, vclock, hlc);\n\n// after\nimport { ConcurrentWriteError } from '../infrastructure/federated-event-store.js';\ntry {\n  await store.applyRemoteEvent(ev, vclock, hlc);\n} catch (e) {\n  if (e instanceof ConcurrentWriteError) {\n    await workStealing.resolveContest(ev.aggregateId, localClaimant, 'concurrent-write');\n    return;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import { ConcurrentWriteError } from './federated-event-store.js';\ntry { await store.applyRemoteEvent(ev, vclock, hlc); }\ncatch (e) {\n  if (e instanceof ConcurrentWriteError) {\n    await workStealing.contestSteal(ev.aggregateId, localClaimant, 'concurrent write');\n    await workStealing.resolveContest(ev.aggregateId, decidedWinner, 'queen decision');\n    return;\n  }\n  throw e;\n}","preventionTips":["Enforce single-writer per aggregate: only the claim owner/lease holder emits events","Sync bidirectionally before a rejoined node starts writing again","Deduplicate identical replayed events so clocks never become concurrent from re-delivery","Monitor for ConcurrentWriteError frequency — a spike means ownership is not being respected"],"tags":["distributed-systems","vector-clock","event-sourcing","conflict","federation","typescript"],"backgroundTag":"optimistic-concurrency-conflict","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}