ianstormtaylor/slate · error · Error
Cannot get the child of a text node: ${Scrubber.stringify(ro
Error message
Cannot get the child of a text node: ${Scrubber.stringify(root)} What it means
Node.child(root, index) returns the index-th child of a node. Text nodes are leaves and have no children, so calling child on a text node throws with a stringified copy of it. This guards against treating a leaf as a branch during tree descent.
Source
Thrown at packages/slate/src/interfaces/node.ts:271
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 entry
}
},
child(root: Node, index: number): Descendant {
if (Node.isText(root)) {
throw new Error(
`Cannot get the child of a text node: ${Scrubber.stringify(root)}`
)
}
if (typeof index !== 'number') {
throw new Error('Expected index to be a number')
}
const c = root.children[index] as Descendant
if (c == null) {
throw new Error(
`Cannot get child at index \`${index}\` in node: ${Scrubber.stringify(
root
)}`
)
}
View on GitHub (pinned to 72a37c701e)
Solutions
- Guard with if (Node.isText(node)) before calling Node.child
- Use Node.has, Node.get, or Editor.nodes for traversal — they handle leaves correctly
- Validate deserialized content ensures text is always wrapped in elements at the levels your code descends
Example fix
// before const step = (node, i) => Node.child(node, i) // crashes on text nodes // after const step = (node, i) => Node.isText(node) ? null : Node.child(node, i)
Defensive patterns
Strategy: type-guard
Validate before calling
if (!Node.isText(node)) {
const c = Node.child(node, index)
} Type guard
const isDescendable = (node) => !Node.isText(node)
Prevention
- Always test Node.isText before descending
- Prefer Node.get/Editor.nodes which handle leaves
- Validate deserialized trees wrap text in elements
When it happens
Trigger: Calling Node.child(textNode, 0); loops that descend via Node.child without checking Node.isText; passing a text node where an element was expected (e.g. from a wrong Node.get result).
Common situations: Custom tree-walking or rendering code that assumes every node has children; deserialized HTML producing bare text where an element was expected; mutation bugs that replace elements with text nodes in place.
Related errors
- Cannot get child at index \`${index}\` in node: ${Scrubber.s
- Unexpected hyperscript child object: ${child}
- The <text> hyperscript tag must only contain a single node's
- The <text> hyperscript tag can only contain text conten
- Cannot get the next node from the root node!
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/72dd500fbb8bbaa9.
Report an issue: GitHub.