Note content out of sync
The notes editor uses a Yjs CRDT for live multi-cursor collaboration.
The CRDT state is cached in Redis as a snapshot; the canonical body
is Note.body in MariaDB (written by REST autosave). Divergence
between the two is the cause of most "out of sync" symptoms.
Symptom: Reload shows old content#
You typed, you saw your text appear, you reload the page, and the note rolls back to an older state.
Cause: REST autosave didn't fire (or failed silently); the CRDT
state had your edits but Note.body didn't. On reload, the editor
reconciles to Note.body and your edits are lost.
Mitigation: the editor watches for unsaved changes and warns on navigation. If you ignored the warning, the unsaved text is gone.
Symptom: Two devices show different content#
Multiple devices editing the same note at once should sync via Yjs. If they don't:
- Yjs WebSocket disconnected on one side. The editor shows a disconnected indicator; reconnect by reloading.
- CRDT state diverged because one side was offline for a long
time. The reconciliation favours the latest server-side
Note.bodyon first sync; offline edits in the offline client may be lost.
Symptom: Editor shows different content than preview#
Edit and Preview both render the same source; they should never disagree. If they do:
- Stale render cache in the preview. Switch to Edit and back.
- Markdown bug — preview renderer mishandled something the CodeMirror editor renders fine. File a bug.
Symptom: Note suddenly has someone else's edits I didn't see#
That's how CRDT collaboration works — when two people edit a note at the same time, both their edits merge. You may see a teammate's text appear without a notification (notes don't notify on each edit; only when comments are added or todos change).
Symptom: SW_NOTE_CONFLICT on REST PUT#
A REST PUT to update a note conflicted with concurrent edits via the CRDT. The CRDT path is preferred — use the editor, or read the current state via GET, merge your changes, and PUT again.
Server-side: Yjs snapshot wipe#
If the Redis-cached Yjs snapshots are stale (e.g. after a schema
migration), restart the API; on first boot a one-shot wipe runs
that clears them and reconciles from Note.body. The wipe runs
once per migration version (gated by a Redis flag); subsequent
restarts don't.
If you suspect Yjs state is corrupt for a single note:
1 2 3 4 5 6 7 8 9 10 | |
Re-open the note; it'll seed a fresh snapshot from Note.body.
What's logged#
notes.yjs_snapshot_wipe— first-boot wipe on migration.notes.crdt_reconcile_to_server— editor seeded fromNote.body.notes.autosave_failed— REST autosave PUT errored.
Greppable in your log aggregator.