thedotmack/claude-mem · error
sync hub push: sent operation is not covered by projected_se
Error message
sync hub push: sent operation is not covered by projected_seq
What it means
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.
Source
Thrown at src/services/sync/CloudSync.ts:1077
throw new Error(
`sync hub push: 200 response acknowledgment multiplicity mismatch (expected ${expected}, received ${actual})`
);
}
}
if (ackCounts.size !== sentCounts.size) {
// Defensive: the unknown-tuple branch above should make this impossible.
throw new Error('sync hub push: 200 response acknowledgment multiset mismatch');
}
if (compareCanonicalDecimals(response.head_seq, response.projected_seq) > 0) {
throw new Error('sync hub push: checkpoint order requires head_seq <= projected_seq');
}
for (const ack of response.acked) {
if (compareCanonicalDecimals(ack.seq, response.head_seq) > 0) {
throw new Error('sync hub push: acknowledgment seq exceeds head_seq');
}
if (compareCanonicalDecimals(ack.seq, response.projected_seq) > 0) {
throw new Error('sync hub push: sent operation is not covered by projected_seq');
}
}
}
/**
* Stamp rows / delete outbox entries for a fully validated acknowledgment
* multiset. The hub may return entries in any order.
*/
private stampAcked(acked: AckedOp[], pushed: WireOp[]): void {
const now = Date.now();
const bodies = new Map(pushed.map(op => {
const body = parseCanonicalOperation(op);
return [operationTupleKey({
id: body.id,
kind: body.kind,
entity_rev: body.entity_rev,
operation_sha256: op.operation_sha256,
}), { body, operationSha256: op.operation_sha256 }] as const;View on GitHub (pinned to d768ba3643)
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.
Defensive patterns
Strategy: try-catch
Try / catch
try { await cloudSync.push(pushed); }
catch (e) {
if (e instanceof Error && e.message.includes('not covered by projected_seq')) {
logger.error('SYNC', e.message); // projection lagged behind acks
await scheduleRetry(); return;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- sync hub push: acknowledgment seq exceeds head_seq
- sync hub push: duplicate operation tuple claimed different s
- sync hub push: distinct operation tuples claimed the same se
- sync hub push: checkpoint order requires head_seq <= project
- sync hub push: acked[${index}] must be an object
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/eb84ae8334d95a79.
Report an issue: GitHub.