ianstormtaylor/slate · error · Error
Cannot apply a "merge_node" operation at path [${path}] to n
Error message
Cannot apply a "merge_node" operation at path [${path}] to nodes of different interfaces: ${Scrubber.stringify(
node
)} ${Scrubber.stringify(prev)} What it means
merge_node merges a node into its previous sibling, which only works when both are text nodes or both are element nodes. It throws when one is a text node and the other an element (or otherwise incompatible interfaces), since there is no defined way to merge them.
Source
Thrown at packages/slate/src/interfaces/transforms/general.ts:117
`Cannot apply a "merge_node" operation at path [${path}] because the root node cannot be merged.`
)
}
// Defend against malicious paths containing strings
if (typeof index !== 'number' || typeof prevIndex !== 'number')
throw new Error('Index must be number')
modifyChildren(editor, Path.parent(path), children => {
const node = children[index]
const prev = children[prevIndex]
let newNode: Descendant
if (Node.isText(node) && Node.isText(prev)) {
newNode = { ...prev, text: prev.text + node.text }
} else if (Node.isElement(node) && Node.isElement(prev)) {
newNode = { ...prev, children: prev.children.concat(node.children) }
} else {
throw new Error(
`Cannot apply a "merge_node" operation at path [${path}] to nodes of different interfaces: ${Scrubber.stringify(
node
)} ${Scrubber.stringify(prev)}`
)
}
return replaceChildren(children, prevIndex, 2, newNode)
})
transformSelection = true
break
}
case 'move_node': {
const { path, newPath } = op
const index = path[path.length - 1]
if (Path.isAncestor(path, newPath)) {View on GitHub (pinned to 72a37c701e)
Solutions
- Before merging, check that Node.isText matches for both the node and its previous sibling; if they differ, use Transforms.wrapNodes/unwrapNodes or remove one instead.
- Run your editor with a schema/normalizer so parents only ever contain homogeneous mergeable children.
- Validate the document structure after deserializing HTML/Markdown before applying merges.
Example fix
// before
Transforms.mergeNodes(editor, { at: path })
// after
const node = Node.get(editor, path)
const prev = Node.get(editor, Path.previous(path))
if (Node.isText(node) === Node.isText(prev)) {
Transforms.mergeNodes(editor, { at: path })
} else {
Transforms.removeNodes(editor, { at: path })
} Defensive patterns
Strategy: type-guard
Validate before calling
const node = Node.get(editor, path)
const prev = Node.get(editor, Path.previous(path))
if (Node.isText(node) === Node.isText(prev)) {
Transforms.mergeNodes(editor, { at: path })
} Type guard
function areMergeable(a: Node, b: Node): boolean {
return (Node.isText(a) && Node.isText(b)) || (Node.isElement(a) && Node.isElement(b))
} Try / catch
try {
Transforms.mergeNodes(editor, { at: path })
} catch (e) {
if (e instanceof Error && e.message.includes('different interfaces')) {
Transforms.removeNodes(editor, { at: path })
} else throw e
} Prevention
- Enforce content schemas with withNormalization so children are homogeneous.
- Validate deserialized documents before applying merge transforms.
- Check node kinds before custom merge logic.
When it happens
Trigger: Applying merge_node at a path whose node is a text node while the previous sibling is an element, or vice versa — e.g. merging path [1] where [0] is an element and [1] is a text node; often from hand-built operations or a document whose children violate Slate's content schema.
Common situations: Documents with mixed invalid children (element containing both element and text children directly where schema forbids it); custom normalizers that merge nodes without checking node types; replaying operations against a diverged document.
Related errors
- Cannot apply a "merge_node" operation at path [${path}] beca
- Index must be number
- Cannot set the "${key}" property of nodes!
- Cannot resolve a Slate range from a DOM event: ${event}
- Unable to find the path for Slate node: ${Scrubber.stringify
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/218273dfcd5a6202.
Report an issue: GitHub.