#4086·claude-mem

Cloud sync permanently blocked by revision_hash_conflict after local DB merge — no client-side way to rebase sync state

Author: timreedzCreated Sep 14, 2026Updated Sep 14, 2026

Version: claude-mem 13.24.1, macOS, worker runtime

Symptom

SyncHub is reachable and authenticated (reachable: true, hub.error: null, quarantine empty), but lastFlushAt is permanently null. Every push is rejected:

sync hub push 400: {"error":"invalid_ops: revision_hash_conflict:observation:<entity-id>:1"}

The error names the same entity every time. The hub's headSeq never advances, so not a single operation has ever landed. Meanwhile the local queue keeps growing — it went from 62,701 to 67,365 mutations over a couple of days and is still climbing.

Background

Two machines share one cmem.ai account. At some point the local SQLite databases were merged by hand (to reconcile memory between the machines). After that merge, local revision hashes diverged from what the hub already knows from the other device — the hub holds ~8,000 entities at revision 1 that this machine now believes are its own new records.

Why this is unrecoverable client-side

There appears to be no supported way to repair this from the client:

  • /api/sync/status is the only registered sync route on the worker; reset, rebase, repair, flush all return 404.
  • The CLI has no sync-repair command either.
  • A single conflicting entity rejects the entire batch, so one bad object blocks the queue indefinitely — every subsequent observation is stuck behind it forever.

The entity id in the error is not derivable from local data (it is not the row id, not content_hash, not a device+id hash), so operators cannot even identify which record to exclude.

Questions

  1. Is there a supported way to rebase/reset a device's sync state so it re-derives revisions from the hub?
  2. Can revisions be recomputed server-side for a device in this state?
  3. Should the client skip/quarantine a conflicting operation rather than rolling back the whole batch? As it stands, one conflict is a permanent, silent stall — pending counts grow but nothing ever ships.