ianstormtaylor/slate · error · Error

Cannot get the element at path [${path}] because it refers t

Error message

Cannot get the element at path [${path}] because it refers to a leaf node: ${Scrubber.stringify(
            node
          )}

What it means

modifyChildren throws when the path refers to a Text (leaf) node but an element (container with children) is required. Transforms that operate on element children (e.g. splitting, merging, inserting nodes) need the target to be an Element; a leaf text node has no children to modify.

Source

Thrown at packages/slate/src/utils/modify.ts:69

  const index = slicedPath.pop()!
  root.children = replaceChildren(root.children, index, 1, modifiedNode)
}

/**
 * Replace the children of a node, replacing all ancestors
 */
export const modifyChildren = (
  root: Ancestor,
  path: Path,
  f: (children: Descendant[]) => Descendant[]
) => {
  if (path.length === 0) {
    root.children = f(root.children)
  } else {
    modifyDescendant<Element>(root, path, node => {
      if (Node.isText(node)) {
        throw new Error(
          `Cannot get the element at path [${path}] because it refers to a leaf node: ${Scrubber.stringify(
            node
          )}`
        )
      }

      return { ...node, children: f(node.children) }
    })
  }
}

/**
 * Replace a leaf, replacing all ancestors
 */
export const modifyLeaf = (
  root: Ancestor,
  path: Path,
  f: (leaf: Text) => Text

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Check Node.isElement(Editor.node(editor, path)[0]) before calling element-level transforms
  2. Use Path.parent(path) to operate on the containing element when you meant the element
  3. Inspect the document (logger or React DevTools) at the failing path to correct path assumptions

Example fix

// before
Transforms.splitNodes(editor, { at: textPath })

// after
const [node] = Editor.node(editor, at)
if (Element.isElement(node)) {
  Transform.splitNodes(editor, { at })
} else {
  Transform.splitNodes(editor, { at: Path.parent(at) })
}
Defensive patterns

Strategy: type-guard

Validate before calling

const [node] = Editor.node(editor, path)
if (!Element.isElement(node)) {
  path = Path.parent(path)
}
Transforms.splitNodes(editor, { at: path })

Type guard

const isElementAt = (editor: Editor, p: Path): boolean =>
  Element.isElement(Editor.node(editor, p)[0])

Prevention

When it happens

Trigger: A transform like splitNodes/mergeNodes/insertNodes given an at/element path resolving to a Text node; calling modifyChildren (directly or via ops) with a path ending at a text leaf, e.g. [0, 0] where node [0,0] is text.

Common situations: Path arithmetic that walks one level too deep (targeting text instead of its parent element); custom transforms assuming a node is an element without checking; mixed content where expected element position holds text.

Related errors


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