docs/solutions/logic-errors/2026-05-04-single-block-fragment-replacement-must-preserve-target-block-before-full-document-replace.md
Rich Slate fragment insertion could downgrade the receiving block when the selection covered the entire single-block document. The full-document replace fast path ran before target-block ownership had a chance to preserve the receiving block wrapper.
Handle the one-block text replacement case before the generic full-document replace path.
if (
editorChildren.length === 1 &&
fragment.length === 1 &&
isTextBlockElement(editor, onlyEditorNode) &&
isTextBlockElement(editor, onlyFragmentNode)
) {
replaceSnapshot(editor, {
children: [
{
...onlyEditorNode,
children: onlyFragmentNode.children,
},
],
selection: getBlockChildrenEndSelection([0], onlyFragmentNode.children),
})
return
}
Then keep the normal empty-target path aligned by unwrapping a single text-block fragment into the receiving empty block instead of inserting the fragment wrapper as the new block.
There are two different ownership policies:
The failing case looked like the first policy because the range covered the whole document, but semantically it was the second policy. The fix checks that small target-owned shape before the broad replace path.