{"record":{"id":"0056d007ffc3f8f5","repo":"neoclide/coc.nvim","slug":"unable-to-find-parent-marker-in-range-json-strin","errorCode":null,"errorMessage":"Unable to find parent marker in range ${JSON.stringify(range, null, 2)}","messagePattern":"Unable to find parent marker in range (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/snippets/snippet.ts","lineNumber":173,"sourceCode":"    })\n    for (let index = list.length - 1; index >= 0; index--) {\n      const o = list[index]\n      if (rangeInRange(range, o.range)) {\n        // Gives choice and final placeholder lower priority for text insert\n        if (isInsert\n          && o.marker instanceof Placeholder\n          && (o.marker.choice || o.marker.index === 0)\n          && o.marker !== current\n          && adjacentPosition(range.start, o.range)\n        ) {\n          continue\n        }\n        marker = o.marker\n        markerRange = o.range\n        break\n      }\n    }\n    if (!marker) throw new Error(`Unable to find parent marker in range ${JSON.stringify(range, null, 2)}`)\n    return { marker, range: markerRange }\n  }\n\n  /**\n   * The change must happens with same marker parents, return the changed marker\n   */\n  public replaceWithMarker(range: Range, marker: Marker, current?: Placeholder): Marker {\n    // the range should already inside this.range\n    const isInsert = emptyRange(range)\n    const result = this.findParent(range, current)\n    let parentMarker = result.marker\n    let parentRange = result.range\n    // search children need to be replaced\n    const children = parentMarker.children\n    let pos = parentRange.start\n    let startIdx = 0\n    let deleteCount = 0\n    const { start, end } = range","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/snippets/snippet.ts#L155-L191","documentation":"findParent walks snippet markers to locate the marker containing a given range so edits can be applied with correct parent context. If no marker's range covers/associates with the requested range, the snippet structure and the edit range are inconsistent, so it throws. Called from result during snippet edit resolution.","triggerScenarios":"Applying a TextEdit or calling snippet APIs with a range that does not fall inside any marker of the currently resolved snippet (e.g. stale offsets after buffer changed).","commonSituations":"Editing a snippet session after external buffer modifications shifted positions; computing ranges from old coordinates.","solutions":["Recompute the range against the current snippet/buffer state.","Ensure the range lies within the snippet's active region.","Abort or restart the snippet session if the buffer changed underneath it.","Use snippet manager APIs to obtain fresh markers instead of caching ranges."],"exampleFix":"// before\nlet res = snippet.result(/** stale range */ range)\n// after\nlet current = snippetManager.getCurrentSnippet() // revalidate against live state\nif (!current || !contains(current.range, range)) return\nlet res = current.result(range)","handlingStrategy":"type-guard","validationCode":"if (!snippet || !snippet.range) return\nif (!containsRange(snippet.range, range)) return // range outside snippet","typeGuard":"function inSnippetRange(snippet: SnippetSession, range: Range): boolean {\n  return snippet != null && range.start.line >= snippet.range.start.line && range.end.line <= snippet.range.end.line\n}","tryCatchPattern":"try {\n  let res = snippet.result(range)\n} catch (e) {\n  if (String(e.message).startsWith('Unable to find parent marker')) restartSnippetSession()\n}","preventionTips":["Never cache marker ranges across buffer changes.","Recompute ranges immediately before edit operations.","Abort snippet sessions when external edits land inside them.","Use session APIs instead of raw offsets."],"tags":["snippets","range"],"backgroundTag":"marker-range-not-found","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}