ianstormtaylor/slate · error · Error

Cannot apply an "insert_node" operation at path [${path}] be

Error message

Cannot apply an "insert_node" operation at path [${path}] because the destination is past the end of the node.

What it means

When applying an insert_node operation, Slate inserts the node into the parent's children at the operation's final index. It throws when that index exceeds the parent's current children length, since there would be no contiguous position to insert into.

Source

Thrown at packages/slate/src/interfaces/transforms/general.ts:61

   * Transform the editor by an operation.
   */
  transform: (editor: Editor, op: Operation) => void
}

// eslint-disable-next-line no-redeclare
export const GeneralTransforms: GeneralTransforms = {
  transform(editor: Editor, op: Operation): void {
    let transformSelection = false

    switch (op.type) {
      case 'insert_node': {
        const { path, node } = op

        modifyChildren(editor, Path.parent(path), children => {
          const index = path[path.length - 1]

          if (index > children.length) {
            throw new Error(
              `Cannot apply an "insert_node" operation at path [${path}] because the destination is past the end of the node.`
            )
          }

          return insertChildren(children, index, node)
        })

        transformSelection = true
        break
      }

      case 'insert_text': {
        const { path, offset, text } = op
        if (text.length === 0) break

        modifyLeaf(editor, path, node => {
          const before = node.text.slice(0, offset)
          const after = node.text.slice(offset)

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Ensure operations are applied in order against the same document state they were computed from; recompute the insertion index from the live document before applying.
  2. Clamp the index: use Math.min(index, parentChildren.length) when generating the operation.
  3. For collaboration, use a proper OT library or Slate's operation-transforming helpers rather than raw apply.

Example fix

// before
Editor.apply(editor, { type: 'insert_node', path: [0, 5], node }) // parent has 2 children

// after
const parent = Node.get(editor, [0])
const index = Math.min(5, parent.children.length)
Editor.apply(editor, { type: 'insert_node', path: [0, index], node })
Defensive patterns

Strategy: validation

Validate before calling

const parentPath = Path.parent(op.path)
const parent = Node.get(editor, parentPath)
const index = op.path[op.path.length - 1]
if (index <= parent.children.length) {
  Editor.apply(editor, op)
}

Type guard

function isValidInsertPath(editor: Editor, path: Path): boolean {
  const parent = Node.get(editor, Path.parent(path))
  const index = path[path.length - 1]
  return index >= 0 && index <= parent.children.length
}

Try / catch

try {
  Editor.apply(editor, op)
} catch (e) {
  if (e instanceof Error && e.message.includes('insert_node')) {
    // skip or re-derive the index from the current document
  } else throw e
}

Prevention

When it happens

Trigger: Applying { type: 'insert_node', path: [0, 5] } when node [0] only has 2 children; usually from hand-crafted operations, replaying/transforming remote operations (collaboration), or applying operations against a different document state than they were generated for.

Common situations: OT/collaboration where operations arrive out of order; serializing operations, rebasing them, then applying to a diverged doc; off-by-one path math after deletions; applying queued operations after the editor was reset.

Related errors


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