ianstormtaylor/slate · error · Error
Cannot get the ancestor node at path [${path}] because it re
Error message
Cannot get the ancestor node at path [${path}] because it refers to a text node instead: ${Scrubber.stringify(
node
)} What it means
Node.ancestor(root, path) expects a path to an element (Ancestor = Editor | Element). If the node at that path is a text node, it cannot be an ancestor, so Slate throws with a stringified copy of the offending node. Note it throws on TEXT nodes specifically; paths pointing past the tree have their own errors.
Source
Thrown at packages/slate/src/interfaces/node.ts:247
*/
string: (node: Node) => string
/**
* Return a generator of all leaf text nodes in a root node.
*/
texts: (
root: Node,
options?: NodeTextsOptions
) => Generator<NodeEntry<Text>, void, undefined>
}
// eslint-disable-next-line no-redeclare
export const Node: NodeInterface = {
ancestor(root: Node, path: Path): Ancestor {
const node = Node.get(root, path)
if (Node.isText(node)) {
throw new Error(
`Cannot get the ancestor node at path [${path}] because it refers to a text node instead: ${Scrubber.stringify(
node
)}`
)
}
return node
},
*ancestors(
root: Node,
path: Path,
options: NodeAncestorsOptions = {}
): Generator<NodeEntry<Ancestor>, void, undefined> {
for (const p of Path.ancestors(path, options)) {
const n = Node.ancestor(root, p)
const entry: NodeEntry<Ancestor> = [n, p]
yield entryView on GitHub (pinned to 72a37c701e)
Solutions
- Check the node kind first with Node.get + Node.isText (or Text.matches) before calling ancestor
- For point/selection paths, use Editor.parent(editor, point.path) which correctly returns the element containing the text node, rather than ancestor on the text path itself
- Fix path arithmetic — text nodes live at the deepest level, so their parent element is Path.parent(textPath)
Example fix
// before const anc = Node.ancestor(editor, [0, 0]) // [0,0] is a text node -> throws // after const anc = Node.ancestor(editor, Path.parent([0, 0])) // the element // or: const [[, el]] = Editor.parent(editor, [0, 0])
Defensive patterns
Strategy: type-guard
Validate before calling
const node = Node.get(editor, path)
if (!Node.isText(node)) {
const anc = Node.ancestor(editor, path)
} Type guard
const isAncestorPath = (root, path) => !Node.isText(Node.get(root, path))
Prevention
- Use Editor.parent for selection-derived paths
- Apply Path.parent to text paths before ancestor lookups
- Check Node.isText before treating a node as an ancestor
When it happens
Trigger: Calling Node.ancestor(editor, [0, 0]) where [0,0] is a text node; Editor.parent or other APIs that delegate to ancestor receiving a text-node path; passing an odd-path (leaf-level path) computed from a Range/Point offset path.
Common situations: Off-by-one path math when navigating from a selection point path to its parent element; assuming a path refers to an element when the document nests text differently than expected.
Related errors
- Cannot get the relative path of [${path}] inside ancestor [$
- Unable to find the path for Slate node: ${Scrubber.stringify
- Cannot get the next node from the root node!
- Cannot get the previous node from the root node!
- Cannot get the child of a text node: ${Scrubber.stringify(ro
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/fe6dad54d1f57fc0.
Report an issue: GitHub.