Notes editor: repeated block drags corrupt paragraph text #1619

Open
opened 2026-10-12 16:11:00 +00:00 by kayg · 1 comment
Owner

Severity: DATA LOSS.

Found by the Notes block editor hunt (owner focus, 2026-10-12). Repro scripts are on dev (6fefd4a62) in apps/web/e2e/break-editor/. Run from apps/web after bun run build: node e2e/break-editor/<script>. Exit 1 = reproduced, 0 = fixed. Server used: prebuilt rev 8e8409629 (same as production). The scripts leave calternal-server-release processes behind; kill them after each run.

Symptom

Three block-handle drags in a row on a Note with paragraphs "Para A" … "Para F" corrupt text: "Para A" becomes "Para AC", "Para D" becomes "Para DF", "Para C" is gone. The corruption reaches the .md file.

Script: 15-drag-corrupts-paragraph-text.mjs, 3/3. Cause not found yet. First step: find out whether the editor state is already wrong before sync (web) or the server merge produces it (collab).

Done when

Script 15 exits 0 three runs in a row, with a unit test at the layer that was wrong.

**Severity: DATA LOSS.** Found by the Notes block editor hunt (owner focus, 2026-10-12). Repro scripts are on `dev` (6fefd4a62) in `apps/web/e2e/break-editor/`. Run from `apps/web` after `bun run build`: `node e2e/break-editor/<script>`. Exit 1 = reproduced, 0 = fixed. Server used: prebuilt rev 8e8409629 (same as production). The scripts leave `calternal-server-release` processes behind; kill them after each run. ## Symptom Three block-handle drags in a row on a Note with paragraphs "Para A" … "Para F" corrupt text: "Para A" becomes "Para AC", "Para D" becomes "Para DF", "Para C" is gone. The corruption reaches the .md file. Script: `15-drag-corrupts-paragraph-text.mjs`, 3/3. Cause not found yet. First step: find out whether the editor state is already wrong before sync (web) or the server merge produces it (collab). ## Done when Script 15 exits 0 three runs in a row, with a unit test at the layer that was wrong.
Author
Owner

Triage (web agent, server rev 8e8409629): the corruption comes from the SERVER, not the editor.

  • The ProseMirror doc and the client's own Yjs doc are correct after each drag (local changes only).
  • About 50 ms after the third drag's 60-byte update is sent, a 158-byte server update arrives and the client applies it as remote. It turns the correct order B D C F A into B D F A AC DF, which then reaches the .md file.
  • Replaying every client-sent update through reference Yjs gives the correct document; only the server's update corrupts. The server sent nothing back after drags 1 and 2.
  • The result varies between runs (another run: Para D | Para CB | Para AF | Para DC | …).
    Likely area: the server-side repair/checkpoint path in crates/calternal-collab/src/session.rs (prepare_client_checkpoint, prepared.repair) that rewrites the room after a client update. Next: a server job, after #1618 lands (same files). Re-run script 15 against a server that has the #1616 fix (c94c92221) first.
Triage (web agent, server rev 8e8409629): the corruption comes from the SERVER, not the editor. - The ProseMirror doc and the client's own Yjs doc are correct after each drag (local changes only). - About 50 ms after the third drag's 60-byte update is sent, a 158-byte server update arrives and the client applies it as remote. It turns the correct order `B D C F A` into `B D F A AC DF`, which then reaches the .md file. - Replaying every client-sent update through reference Yjs gives the correct document; only the server's update corrupts. The server sent nothing back after drags 1 and 2. - The result varies between runs (another run: `Para D | Para CB | Para AF | Para DC | …`). Likely area: the server-side repair/checkpoint path in crates/calternal-collab/src/session.rs (`prepare_client_checkpoint`, `prepared.repair`) that rewrites the room after a client update. Next: a server job, after #1618 lands (same files). Re-run script 15 against a server that has the #1616 fix (c94c92221) first.
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1619
No description provided.