ianstormtaylor/slate · error · Error
Cannot get child at index \`${index}\` in node: ${Scrubber.s
Error message
Cannot get child at index \`${index}\` in node: ${Scrubber.stringify(
root
)} What it means
Node.child(root, index) throws when root.children[index] is undefined or null — i.e. the requested child index is out of bounds (negative or >= children.length). The message includes the offending index and a stringified copy of the root node to aid debugging.
Source
Thrown at packages/slate/src/interfaces/node.ts:283
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
)}`
)
}
return c
},
*children(
root: Node,
path: Path,
options: NodeChildrenOptions = {}
): Generator<NodeEntry<Descendant>, void, undefined> {
const { reverse = false } = options
const ancestor = Node.ancestor(root, path)
const { children } = ancestor
let index = reverse ? children.length - 1 : 0View on GitHub (pinned to 72a37c701e)
Solutions
- Bounds-check first: 0 <= index < (node.children?.length ?? 0)
- Fix loop conditions — use < children.length, not <=
- Re-read the node or use Node.get/Editor.nodes with paths instead of cached indices after mutations
Example fix
// before
for (let i = 0; i <= node.children.length; i++) {
const c = Node.child(node, i) // throws on last iteration
}
// after
for (let i = 0; i < node.children.length; i++) {
const c = Node.child(node, i)
} Defensive patterns
Strategy: validation
Validate before calling
if (
Number.isInteger(index) &&
index >= 0 &&
index < node.children.length
) {
const c = Node.child(node, index)
} Type guard
const isIndexInBounds = (node, i) => Number.isInteger(i) && i >= 0 && i < node.children.length
Prevention
- Use < not <= in child-iteration loops
- Re-derive indices after mutations instead of caching them
- Bounds-check before indexing into children arrays
When it happens
Trigger: Calling Node.child(node, node.children.length) (classic off-by-one when iterating <= instead of <); using a stale index after children were removed; negative indices; assuming an element has children when it is empty.
Common situations: Loop bounds mistakes in manual traversal; cached paths/indices invalidated by concurrent edits; empty elements (children: []) accessed with index 0.
Related errors
- Cannot get the child of a text node: ${Scrubber.stringify(ro
- Unexpected hyperscript child object: ${child}
- Cannot get the next node from the root node!
- Cannot get the previous node from the root node!
- Cannot get the ancestor node at path [${path}] because it re
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/409361970074f712.
Report an issue: GitHub.