{"record":{"id":"3a2e513b8f95ce17","repo":"ianstormtaylor/slate","slug":"cannot-merge-the-node-at-path-path-with-the-p","errorCode":null,"errorMessage":"Cannot merge the node at path [${path}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(\n          node\n        )} ${Scrubber.stringify(prevNode)}","messagePattern":"Cannot merge the node at path \\[(.+?)\\] with the previous sibling because it is not the same kind: (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/transforms-node/merge-nodes.ts","lineNumber":116,"sourceCode":"      match: n => levels.includes(n) && hasSingleChildNest(editor, n),\n    })\n\n    const emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1])\n    let properties\n    let position\n\n    // Ensure that the nodes are equivalent, and figure out what the position\n    // and extra properties of the merge will be.\n    if (Node.isText(node) && Node.isText(prevNode)) {\n      const { text, ...rest } = node\n      position = prevNode.text.length\n      properties = rest as Partial<Text>\n    } else if (Node.isElement(node) && Node.isElement(prevNode)) {\n      const { children, ...rest } = node\n      position = prevNode.children.length\n      properties = rest as Partial<Element>\n    } else {\n      throw new Error(\n        `Cannot merge the node at path [${path}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(\n          node\n        )} ${Scrubber.stringify(prevNode)}`\n      )\n    }\n\n    // If the node isn't already the next sibling of the previous node, move\n    // it so that it is before merging.\n    if (!isPreviousSibling) {\n      Transforms.moveNodes(editor, { at: path, to: newPath, voids })\n    }\n\n    // If there was going to be an empty ancestor of the node that was merged,\n    // we remove it from the tree.\n    if (emptyRef) {\n      Transforms.removeNodes(editor, { at: emptyRef.current!, voids })\n    }\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/transforms-node/merge-nodes.ts#L98-L134","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nTransforms.mergeNodes(editor, { at })\n\n// after\nconst [prev] = Editor.node(editor, Path.previous(at))\nconst [cur] = Editor.node(editor, at)\nif (Node.isText(prev) === Node.isText(cur)) {\n  Transforms.mergeNodes(editor, { at })\n} else {\n  Transforms.removeNodes(editor, { at })\n}","handlingStrategy":"type-guard","validationCode":"const [cur] = Editor.node(editor, at)\nlet prevEntry\ntry { prevEntry = Editor.node(editor, Path.previous(at)) } catch { prevEntry = null }\nif (prevEntry) {\n  const [prev] = prevEntry\n  if (Node.isText(prev) === Node.isText(cur)) {\n    Transforms.mergeNodes(editor, { at })\n    return\n  }\n}\nTransforms.removeNodes(editor, { at })","typeGuard":"const isSameKind = (a: Node, b: Node): boolean =>\n  Node.isText(a) === Node.isText(b)","tryCatchPattern":null,"preventionTips":["Inspect the previous sibling's kind before merging","Prefer built-in deletion APIs over manual mergeNodes","Guard custom Backspace handlers with kind checks"],"tags":["merge-nodes","node-kind","transform","slate"],"backgroundTag":"incompatible-node-merge","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}