{"record":{"id":"d5fd61c9cbc9f314","repo":"ianstormtaylor/slate","slug":"cannot-get-the-previous-path-of-a-first-child-path","errorCode":null,"errorMessage":"Cannot get the previous path of a first child path [${path}] because it would result in a negative index.","messagePattern":"Cannot get the previous path of a first child path \\[(.+?)\\] because it would result in a negative index\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/interfaces/path.ts","lineNumber":374,"sourceCode":"  parent(path: Path): Path {\n    if (path.length === 0) {\n      throw new Error(`Cannot get the parent path of the root path [${path}].`)\n    }\n\n    return path.slice(0, -1)\n  },\n\n  previous(path: Path): Path {\n    if (path.length === 0) {\n      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(","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/interfaces/path.ts#L356-L392","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check that the last segment of the path is > 0 before calling Path.previous, or use Editor.previous() which returns undefined instead of throwing.","If merging nodes, merge the later node into the previous one — never merge a first child.","Debug the computed path right before the call; it is almost always [.., 0] when this fires."],"exampleFix":"// before\nconst prev = Path.previous(path) // throws if path ends in 0\n\n// after\nconst last = path[path.length - 1]\nconst prev = last > 0 ? Path.previous(path) : null","handlingStrategy":"validation","validationCode":"const last = path[path.length - 1]\nif (last > 0) {\n  const prev = Path.previous(path)\n}","typeGuard":"function hasPreviousSibling(path: Path): boolean {\n  return path.length > 0 && path[path.length - 1] > 0\n}","tryCatchPattern":null,"preventionTips":["Never call Path.previous on a path ending in 0; check the last segment first.","Prefer Editor.previous(), which returns undefined instead of throwing.","Remember merge_node internally uses Path.previous — never merge a first child."],"tags":["slate","path","sibling","bounds-check"],"backgroundTag":"path-index-out-of-bounds","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}