Repository navigation
Description
text-editor: inline code inside bold makes the whole file unopenable
Repo: opencloud-eu/web (web-app-text-editor / Yjs collaboration glue)
Version: OpenCloud server 9.0.0 rolling, Web UI 8.2.1 (Chromium)
Summary
A markdown file containing inline code inside a bold span — e.g. **`Sharing`** — cannot be
opened in the text editor. The whole editor fails, the page reloads in a loop, and the user only
sees:
Collaboration error — Preparing this file for collaborative editing failed. Please reload.
The Yjs service is healthy: the websocket connects, onAuthenticate succeeds and returns
readOnly=false, then the client disconnects immediately. Nothing is wrong server-side; the failure
happens during hydration, in the browser.
Console output
[yjs] hydration failed: Error: [tiptap error]: Invalid JSON content
at Zu (tiptap-vendor-Cf18ApP7.mjs:10:71810)
at Ad (tiptap-vendor-Cf18ApP7.mjs:10:78248)
at Object.setContent (tiptap-vendor-Cf18ApP7.mjs:10:64419)
at Object.hydrate (editor-C_TBqycw.mjs:146:6414)
at Yjs-vA2k3HAq.mjs:11:3560
at ye (Yjs-vA2k3HAq.mjs:11:3523)
at Se (Yjs-vA2k3HAq.mjs:11:4329)
Caused by: RangeError: Invalid collection of marks for node text: bold,code
Reproduction
-
Create a markdown file containing:
| `allowDirectoryQueries = true` sur l'objet **`Sharing`**
-
Open it with the text editor (
/text-editor/...or the files app). -
The editor shows the collaboration error and the page reloads.
Removing the backticks, or the **, makes the file open again. Any file with a bold span that
contains at least one code span is affected (we hit 151 of 532 files in our documentation space).
Analysis
The markdown → ProseMirror JSON conversion produces a text node whose marks array is ordered
[bold, code]. ProseMirror validates marks against the schema's mark order and throws
Invalid collection of marks for node text: bold,code (Node.check). The order is imposed by the
markdown nesting itself: in **x** the code span is inside the bold span, so "bold then code" is
the natural emission order, while the schema ranks them the other way round.
Suggested fixes
- Sort each text node's
marksaccording to the schema mark ranking before handing the document to
setContent(or build the nodes throughschema.text(text, marks)with marks sorted, e.g.
marks.sort((a, b) => schema.marks[a.type.name].rank - schema.marks[b.type.name].rank), or
Mark.setFrom). - Add a regression test with
**`code`**and with a sentence-level bold containing code
(**somecodehere**). - Graceful degradation: when hydration throws, fall back to non-collaborative editing instead of
reloading the page and losing the file entirely. A single markdown construct currently makes the
document completely inaccessible from the web UI.
Environment detail
text-editor::<fileId>:8.2.1 document names confirm the client hardcodes the web version
(function FS(){return "8.2.1"} in Yjs-vA2k3HAq.mjs), so this is not a stale-bundle problem: the
served bundle and the console-reported version match.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity