ianstormtaylor/slate · error · Error
Cannot get the descendant node at path [${path}] because it
Error message
Cannot get the descendant node at path [${path}] because it refers to the root editor node instead: ${Scrubber.stringify(
node
)} What it means
Node.descendant() attempts to resolve a path inside a node tree, but the resolved node is the editor itself. In Slate, the editor is the root container and not a 'descendant', so the API refuses to return it. This almost always means the path was empty ([]) or pointed back to the root.
Source
Thrown at packages/slate/src/interfaces/node.ts:321
while (reverse ? index >= 0 : index < children.length) {
const child = Node.child(ancestor, index)
const childPath = path.concat(index)
yield [child, childPath]
index = reverse ? index - 1 : index + 1
}
},
common(root: Node, path: Path, another: Path): NodeEntry {
const p = Path.common(path, another)
const n = Node.get(root, p)
return [n, p]
},
descendant(root: Node, path: Path): Descendant {
const node = Node.get(root, path)
if (Node.isEditor(node)) {
throw new Error(
`Cannot get the descendant node at path [${path}] because it refers to the root editor node instead: ${Scrubber.stringify(
node
)}`
)
}
return node
},
*descendants(
root: Node,
options: NodeDescendantsOptions = {}
): Generator<NodeEntry<Descendant>, void, undefined> {
for (const [node, path] of Node.nodes(root, options)) {
if (path.length !== 0) {
// NOTE: we have to coerce here because checking the path's length does
// guarantee that `node` is not a `Editor`, but TypeScript doesn't know.
yield [node, path] as NodeEntry<Descendant>View on GitHub (pinned to 72a37c701e)
Solutions
- Check that the path is non-empty and does not resolve to the root before calling descendant: if (path.length === 0) handle root explicitly.
- If you actually want the root, use the editor object directly instead of Node.descendant.
- Use Node.get with your own Editor.isEditor check if you need the root case to be handled generically.
- Verify Path.parent() results: it throws only on [], so guard paths of length 1 before descending further.
Example fix
// before const node = Node.descendant(editor, Path.parent(somePath)) // after const p = Path.parent(somePath) const node = p.length === 0 ? editor : Node.descendant(editor, p)
Defensive patterns
Strategy: type-guard
Validate before calling
if (path.length === 0) { /* root: use editor directly */ } Type guard
const isNonRootPath = (p: Path): boolean => p.length > 0 && !Editor.isEditor(Node.getIf(editor, p))
Prevention
- Never feed Path.parent results into descendant without checking for the empty path.
- Treat [] as the editor and branch explicitly before descendant lookups.
When it happens
Trigger: Calling Node.descendant(editor, []) or Editor.node() with a path of length 0; passing a path computed from Path.parent on a top-level path ([0] -> []); passing an editor where a descendant node was expected.
Common situations: Walking up with Path.parent until the root and then calling descendant on the result; off-by-one in path math that produces an empty path; calling Editor.node(editor, path) where path was normalized to the root.
Related errors
- Cannot get the next node from the root node!
- Cannot get the previous node from the root node!
- Cannot apply a "split_node" operation at path [${path}] beca
- Cannot modify the editor
- 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/8029d7ab6967f0b2.
Report an issue: GitHub.