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

  1. Guard with if (Node.isText(node)) before calling Node.child
  2. Use Node.has, Node.get, or Editor.nodes for traversal — they handle leaves correctly
  3. 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

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


AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27). Data as JSON: /api/errors/72dd500fbb8bbaa9. Report an issue: GitHub.