ianstormtaylor/slate · error · Error
Cannot merge the node at path [${path}] with the previous si
Error message
Cannot merge the node at path [${path}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(
node
)} ${Scrubber.stringify(prevNode)} What it means
mergeNodes throws when the node being merged and its previous sibling are of different kinds — specifically when one is a Text node and the other is an Element, or their structures make merging invalid (e.g. merging an element into a text node). Merging requires both nodes to be the same type so their contents can combine.
Source
Thrown at packages/slate/src/transforms-node/merge-nodes.ts:116
match: n => levels.includes(n) && hasSingleChildNest(editor, n),
})
const emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1])
let properties
let position
// Ensure that the nodes are equivalent, and figure out what the position
// and extra properties of the merge will be.
if (Node.isText(node) && Node.isText(prevNode)) {
const { text, ...rest } = node
position = prevNode.text.length
properties = rest as Partial<Text>
} else if (Node.isElement(node) && Node.isElement(prevNode)) {
const { children, ...rest } = node
position = prevNode.children.length
properties = rest as Partial<Element>
} else {
throw new Error(
`Cannot merge the node at path [${path}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(
node
)} ${Scrubber.stringify(prevNode)}`
)
}
// If the node isn't already the next sibling of the previous node, move
// it so that it is before merging.
if (!isPreviousSibling) {
Transforms.moveNodes(editor, { at: path, to: newPath, voids })
}
// If there was going to be an empty ancestor of the node that was merged,
// we remove it from the tree.
if (emptyRef) {
Transforms.removeNodes(editor, { at: emptyRef.current!, voids })
}
View on GitHub (pinned to 72a37c701e)
Solutions
- Check the target and its previous sibling (or parent for first children) are the same kind (Node.isText on both, or both Elements) before merging
- Use Editor.node(editor, Path.previous(path)) to inspect the prev sibling and skip/unwrap instead
- Prefer built-in Editor.deleteBackward or Transforms.removeNodes for mixed-kind structures instead of manual mergeNodes
Example fix
// before
Transforms.mergeNodes(editor, { at })
// after
const [prev] = Editor.node(editor, Path.previous(at))
const [cur] = Editor.node(editor, at)
if (Node.isText(prev) === Node.isText(cur)) {
Transforms.mergeNodes(editor, { at })
} else {
Transforms.removeNodes(editor, { at })
} Defensive patterns
Strategy: type-guard
Validate before calling
const [cur] = Editor.node(editor, at)
let prevEntry
try { prevEntry = Editor.node(editor, Path.previous(at)) } catch { prevEntry = null }
if (prevEntry) {
const [prev] = prevEntry
if (Node.isText(prev) === Node.isText(cur)) {
Transforms.mergeNodes(editor, { at })
return
}
}
Transforms.removeNodes(editor, { at }) Type guard
const isSameKind = (a: Node, b: Node): boolean => Node.isText(a) === Node.isText(b)
Prevention
- Inspect the previous sibling's kind before merging
- Prefer built-in deletion APIs over manual mergeNodes
- Guard custom Backspace handlers with kind checks
When it happens
Trigger: Transforms.mergeNodes where target is a Text but prev sibling is an Element, or vice versa; merging the first child of an element into the element itself when kinds mismatch; merging nodes at depth where prev sibling is a text while target is an inline element.
Common situations: Custom delete/Backspace handlers calling mergeNodes on arbitrary paths; normalizing structure where text and inline-element siblings are interleaved; calling mergeNodes with at pointing at the first text of an element whose parent merge then mismatches.
Related errors
- Cannot lift node at a path [${path}] because it has a depth
- Cannot resolve a Slate range from a DOM event: ${event}
- Unable to find the path for Slate node: ${Scrubber.stringify
- Could not set focus, editor seems stuck with pending operati
- Unable to find a host window element for this editor
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/3a2e513b8f95ce17.
Report an issue: GitHub.