{"record":{"id":"2440baf9c6c0cf3c","repo":"ianstormtaylor/slate","slug":"cannot-get-the-relative-path-of-path-inside-a","errorCode":null,"errorMessage":"Cannot get the relative path of [${path}] inside ancestor [${ancestor}], because it is not above or equal to the path.","messagePattern":"Cannot get the relative path of \\[(.+?)\\] inside ancestor \\[(.+?)\\], because it is not above or equal to the path\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/interfaces/path.ts","lineNumber":384,"sourceCode":"      throw new Error(\n        `Cannot get the previous path of a root path [${path}], because it has no previous index.`\n      )\n    }\n\n    const last = path[path.length - 1]\n\n    if (last <= 0) {\n      throw new Error(\n        `Cannot get the previous path of a first child path [${path}] because it would result in a negative index.`\n      )\n    }\n\n    return path.slice(0, -1).concat(last - 1)\n  },\n\n  relative(path: Path, ancestor: Path): Path {\n    if (!Path.isAncestor(ancestor, path) && !Path.equals(path, ancestor)) {\n      throw new Error(\n        `Cannot get the relative path of [${path}] inside ancestor [${ancestor}], because it is not above or equal to the path.`\n      )\n    }\n\n    return path.slice(ancestor.length)\n  },\n\n  transform(\n    path: Path | null,\n    operation: Operation,\n    options: PathTransformOptions = {}\n  ): Path | null {\n    if (!path) return null\n\n    // PERF: use destructing instead of immer\n    const p = [...path]\n    const { affinity = 'forward' } = options\n","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/interfaces/path.ts#L366-L402","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Verify argument order: Path.relative(path, ancestor) — ancestor is the SECOND argument.","Pre-check with Path.isAncestor(ancestor, path) || Path.equals(ancestor, path) and handle the false case gracefully.","If paths may be stale, recompute them from the current document (e.g. via Editor.above / Node.first) before calling."],"exampleFix":"// before\nconst rel = Path.relative(path, ancestor) // throws when not above\n\n// after\nconst rel =\n  Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)\n    ? Path.relative(path, ancestor)\n    : null","handlingStrategy":"validation","validationCode":"if (Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)) {\n  const rel = Path.relative(path, ancestor)\n}","typeGuard":"function isPathAboveOrEqual(ancestor: Path, path: Path): boolean {\n  return Path.isAncestor(ancestor, path) || Path.equals(ancestor, path)\n}","tryCatchPattern":null,"preventionTips":["ancestor is the second argument — double-check argument order.","Recompute paths from the live document before deriving relative paths.","Unit-test path math around sibling/descendant inputs."],"tags":["slate","path","ancestor","validation"],"backgroundTag":"path-validation-failed","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}