ianstormtaylor/slate · error · Error

Cannot get the relative path of [${path}] inside ancestor [$

Error message

Cannot get the relative path of [${path}] inside ancestor [${ancestor}], because it is not above or equal to the path.

What it means

Path.relative(path, ancestor) returns the portion of path below ancestor. It throws when the ancestor argument is not actually an ancestor of (or equal to) path, i.e. ancestor is a sibling, descendant, or unrelated path.

Source

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

      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(
    path: Path | null,
    operation: Operation,
    options: PathTransformOptions = {}
  ): Path | null {
    if (!path) return null

    // PERF: use destructing instead of immer
    const p = [...path]
    const { affinity = 'forward' } = options

View on GitHub (pinned to 72a37c701e)

Solutions

  1. Verify argument order: Path.relative(path, ancestor) — ancestor is the SECOND argument.
  2. Pre-check with Path.isAncestor(ancestor, path) || Path.equals(ancestor, path) and handle the false case gracefully.
  3. If paths may be stale, recompute them from the current document (e.g. via Editor.above / Node.first) before calling.

Example fix

// before
const rel = Path.relative(path, ancestor) // throws when not above

// after
const rel =
  Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)
    ? Path.relative(path, ancestor)
    : null
Defensive patterns

Strategy: validation

Validate before calling

if (Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)) {
  const rel = Path.relative(path, ancestor)
}

Type guard

function isPathAboveOrEqual(ancestor: Path, path: Path): boolean {
  return Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)
}

Prevention

When it happens

Trigger: Calling Path.relative([0,1],[1]) or Path.relative([0,0],[0,1,0]) — any pair where Path.isAncestor(ancestor, path) is false and Path.equals(path, ancestor) is false. Common with computed paths in custom transforms where the ancestor was derived from a different subtree.

Common situations: Passing a node's own descendant as the 'ancestor'; reusing a stale ancestor path after the document changed; confusing argument order (ancestor must come second).

Related errors


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