{"record":{"id":"3981fbbb13f2ae42","repo":"ianstormtaylor/slate","slug":"cannot-apply-a-split-node-operation-at-path-p","errorCode":null,"errorMessage":"Cannot apply a \"split_node\" operation at path [${path}] because the root node cannot be split.","messagePattern":"Cannot apply a \"split_node\" operation at path \\[(.+?)\\] because the root node cannot be split\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/interfaces/transforms/general.ts","lineNumber":354,"sourceCode":"            }\n\n            delete selection[<keyof Range>key]\n          } else {\n            selection[<keyof Range>key] = value\n          }\n        }\n\n        editor.selection = selection\n\n        break\n      }\n\n      case 'split_node': {\n        const { path, position, properties } = op\n        const index = path[path.length - 1]\n\n        if (path.length === 0) {\n          throw new Error(\n            `Cannot apply a \"split_node\" operation at path [${path}] because the root node cannot be split.`\n          )\n        }\n\n        // Defend against malicious paths containing strings\n        if (typeof index !== 'number') throw new Error('Index must be number')\n\n        modifyChildren(editor, Path.parent(path), children => {\n          const node = children[index]\n          let newNode: Descendant\n          let nextNode: Descendant\n\n          if (Node.isText(node)) {\n            const before = node.text.slice(0, position)\n            const after = node.text.slice(position)\n            newNode = {\n              ...node,\n              text: before,","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/interfaces/transforms/general.ts#L336-L372","documentation":"A split_node operation was applied with an empty path [], which refers to the root editor node. The root node has no parent, so it cannot be split; split_node always targets a child within a parent.","triggerScenarios":"Transforms.splitNodes(editor, { at: [] }); Editor.applyEditorOp/transform receiving split_node with path.length === 0; manual op construction with an empty path.","commonSituations":"Computing split paths with Path.parent/Path.next and accidentally producing []; replaying corrupted or hostile operation logs; off-by-one path math in custom transforms.","solutions":["Guard before splitting: ensure the target path is non-empty (path.length > 0)","Fix the path computation that produced the root path; split a child node instead","Validate/sanitize operations before applying them if they come from remote/serialized sources"],"exampleFix":"// before\nTransforms.splitNodes(editor, { at: [] })\n\n// after\nif (at && at.length > 0) {\n  Transforms.splitNodes(editor, { at })\n}","handlingStrategy":"type-guard","validationCode":"if (!at || Path.isPath(at) === false || at.length === 0) {\n  throw new Error('Cannot split the root node')\n}\nTransforms.splitNodes(editor, { at })","typeGuard":"const isChildPath = (p: Path): boolean => Array.isArray(p) && p.length > 0 && p.every(n => typeof n === 'number')","tryCatchPattern":null,"preventionTips":["Never call splitNodes with the root path []","Log paths during transform development to catch empty-path bugs","Validate op shapes when accepting operations from remote sources"],"tags":["split-node","path","root-node","slate"],"backgroundTag":"invalid-path-operation","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}