What happened?
In suggesting mode, inserting a paragraph via a markdown Document-API insert records a tracked change that can never be resolved, and which makes acceptAllTrackedChanges() fail for the entire document (it resolves nothing while this change exists).
trackChanges.list() reports it as a normal insert, but resolving it fails:
editor.doc.trackChanges.decide({ decision: 'accept', target: { kind: 'id', id } })
// => { success: false, failure: { code: 'PRECONDITION_FAILED',
// message: 'replacement "<id>" missing inserted or deleted side.' } }
acceptAllTrackedChanges() returns false and clears nothing — a healthy tracked change in the same document is left unresolved too. (Individual by-id accept of a healthy change still works; it is the malformed change and the bulk accept-all path that are stuck.) A plain (non-markdown) text insert produces a clean, acceptable tracked change.
Markdown inserts throw a "tracked mode" capability error (Tracked mode is not supported for type: 'markdown' insert operations.), so callers apply them in changeMode: 'direct' — yet the direct apply still stamps a trackInsert mark, i.e. a direct edit leaks an unresolvable tracked change. Disabling track changes on the editor before the insert avoids the mark, which points at the direct path not honoring its own change mode.
Steps to reproduce
Manually:
- Open a document with
documentMode: 'suggesting' and a user set.
- Insert a paragraph as markdown via the Document API (
{ type: 'markdown', value }); tracked mode throws, so it applies in changeMode: 'direct'.
editor.doc.trackChanges.list() → the markdown change appears, type: 'insert'.
editor.doc.trackChanges.decide({ decision: 'accept', target: { kind: 'id', id: <that id> } }) → success: false,
PRECONDITION_FAILED: replacement "<id>" missing inserted or deleted side.
5. With that change present, editor.commands.acceptAllTrackedChanges() → false, and trackChanges.list().total is unchanged — including any healthy sibling change.
Reproduced headless under Node/Bun — engine/converter issue, not rendering. You can use the minimal eproducible example attached as well.
superdoc-trackchanges-repro.js
SuperDoc version
1.42.0 (also via @superdoc-dev/sdk 1.18.0)
Browser
None
Additional context
Looks like the same inline-only track-model root cause as #3592 (structural edits have no tracked representation) and the silent-direct class in #3594 — but the failure here is worse: a malformed "replacement" that is permanently unresolvable and breaks Accept All, rather than a silent direct apply.
What happened?
In suggesting mode, inserting a paragraph via a markdown Document-API insert records a tracked change that can never be resolved, and which makes
acceptAllTrackedChanges()fail for the entire document (it resolves nothing while this change exists).trackChanges.list()reports it as a normalinsert, but resolving it fails:acceptAllTrackedChanges()returnsfalseand clears nothing — a healthy tracked change in the same document is left unresolved too. (Individual by-id accept of a healthy change still works; it is the malformed change and the bulk accept-all path that are stuck.) A plain (non-markdown) text insert produces a clean, acceptable tracked change.Markdown inserts throw a "tracked mode" capability error (
Tracked mode is not supported for type: 'markdown' insert operations.), so callers apply them inchangeMode: 'direct'— yet the direct apply still stamps atrackInsertmark, i.e. a direct edit leaks an unresolvable tracked change. Disabling track changes on the editor before the insert avoids the mark, which points at the direct path not honoring its own change mode.Steps to reproduce
Manually:
documentMode: 'suggesting'and auserset.{ type: 'markdown', value }); tracked mode throws, so it applies inchangeMode: 'direct'.editor.doc.trackChanges.list()→ the markdown change appears,type: 'insert'.editor.doc.trackChanges.decide({ decision: 'accept', target: { kind: 'id', id: <that id> } })→success: false,PRECONDITION_FAILED: replacement "<id>" missing inserted or deleted side.5. With that change present,
editor.commands.acceptAllTrackedChanges()→false, andtrackChanges.list().totalis unchanged — including any healthy sibling change.Reproduced headless under Node/Bun — engine/converter issue, not rendering. You can use the minimal eproducible example attached as well.
superdoc-trackchanges-repro.js
SuperDoc version
1.42.0 (also via @superdoc-dev/sdk 1.18.0)
Browser
None
Additional context
Looks like the same inline-only track-model root cause as #3592 (structural edits have no tracked representation) and the silent-direct class in #3594 — but the failure here is worse: a malformed "replacement" that is permanently unresolvable and breaks Accept All, rather than a silent direct apply.