ianstormtaylor/slate · error · Error

Cannot get the previous path of a first child path [${path}]

Error message

Cannot get the previous path of a first child path [${path}] because it would result in a negative index.

What it means

Path.previous() returns the path of the sibling immediately before the given path. It throws when called on a path whose final index is 0 (or negative), because decrementing it would produce a negative index, which cannot correspond to a real node.

Source

Thrown at packages/slate/src/interfaces/path.ts:374

  parent(path: Path): Path {
    if (path.length === 0) {
      throw new Error(`Cannot get the parent path of the root path [${path}].`)
    }

    return path.slice(0, -1)
  },

  previous(path: Path): Path {
    if (path.length === 0) {
      throw new Error(
        `Cannot get the previous path of a root path [${path}], because it has no previous index.`
      )
    }

    const last = path[path.length - 1]

    if (last <= 0) {
      throw new Error(
        `Cannot get the previous path of a first child path [${path}] because it would result in a negative index.`
      )
    }

    return path.slice(0, -1).concat(last - 1)
  },

  relative(path: Path, ancestor: Path): Path {
    if (!Path.isAncestor(ancestor, path) && !Path.equals(path, ancestor)) {
      throw new Error(
        `Cannot get the relative path of [${path}] inside ancestor [${ancestor}], because it is not above or equal to the path.`
      )
    }

    return path.slice(ancestor.length)
  },

  transform(

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Check that the last segment of the path is > 0 before calling Path.previous, or use Editor.previous() which returns undefined instead of throwing.
  2. If merging nodes, merge the later node into the previous one — never merge a first child.
  3. Debug the computed path right before the call; it is almost always [.., 0] when this fires.

Example fix

// before
const prev = Path.previous(path) // throws if path ends in 0

// after
const last = path[path.length - 1]
const prev = last > 0 ? Path.previous(path) : null
Defensive patterns

Strategy: validation

Validate before calling

const last = path[path.length - 1]
if (last > 0) {
  const prev = Path.previous(path)
}

Type guard

function hasPreviousSibling(path: Path): boolean {
  return path.length > 0 && path[path.length - 1] > 0
}

Prevention

When it happens

Trigger: Calling Path.previous([0]) or Path.previous([1,0]) — any path whose last segment is 0. Often reached indirectly via Editor.previous(), Transforms.removeNodes with at pointing at a first child, or applying a merge_node operation on a first sibling since merge_node computes Path.previous(path) internally.

Common situations: Iterating siblings backwards without a bounds check; custom normalization logic that assumes every node has a previous sibling; merging the first child of an element; off-by-one errors in computed paths after removals.

Related errors


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