{"record":{"id":"72dd500fbb8bbaa9","repo":"ianstormtaylor/slate","slug":"cannot-get-the-child-of-a-text-node-scrubber-st","errorCode":null,"errorMessage":"Cannot get the child of a text node: ${Scrubber.stringify(root)}","messagePattern":"Cannot get the child of a text node: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/interfaces/node.ts","lineNumber":271,"sourceCode":"\n    return node\n  },\n\n  *ancestors(\n    root: Node,\n    path: Path,\n    options: NodeAncestorsOptions = {}\n  ): Generator<NodeEntry<Ancestor>, void, undefined> {\n    for (const p of Path.ancestors(path, options)) {\n      const n = Node.ancestor(root, p)\n      const entry: NodeEntry<Ancestor> = [n, p]\n      yield entry\n    }\n  },\n\n  child(root: Node, index: number): Descendant {\n    if (Node.isText(root)) {\n      throw new Error(\n        `Cannot get the child of a text node: ${Scrubber.stringify(root)}`\n      )\n    }\n\n    if (typeof index !== 'number') {\n      throw new Error('Expected index to be a number')\n    }\n\n    const c = root.children[index] as Descendant\n\n    if (c == null) {\n      throw new Error(\n        `Cannot get child at index \\`${index}\\` in node: ${Scrubber.stringify(\n          root\n        )}`\n      )\n    }\n","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/interfaces/node.ts#L253-L289","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst step = (node, i) => Node.child(node, i) // crashes on text nodes\n\n// after\nconst step = (node, i) =>\n  Node.isText(node) ? null : Node.child(node, i)","handlingStrategy":"type-guard","validationCode":"if (!Node.isText(node)) {\n  const c = Node.child(node, index)\n}","typeGuard":"const isDescendable = (node) => !Node.isText(node)","tryCatchPattern":null,"preventionTips":["Always test Node.isText before descending","Prefer Node.get/Editor.nodes which handle leaves","Validate deserialized trees wrap text in elements"],"tags":["slate","node-api","text-node","children","traversal"],"backgroundTag":"invalid-node-path","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}