neoclide/coc.nvim · error
Parent placeholder has same index: ${idx}
Error message
Parent placeholder has same index: ${idx} What it means
checkParentPlaceHolders validates snippet marker nesting: a Placeholder must not have an ancestor Placeholder with the same index, since $1 inside $1 makes replacement semantics ambiguous. The snippet parser calls it after parsing to reject malformed snippet definitions.
Source
Thrown at src/snippets/parser.ts:431
if (this.transform) {
ret.transform = this.transform.clone()
}
ret.id = this.id
ret.primary = this.primary
ret._children = this.children.map(child => {
let m = child.clone()
m.parent = ret
return m
})
return ret
}
public checkParentPlaceHolders(): void {
let idx = this.index
let p = this.parent
while (p != null && !(p instanceof TextmateSnippet)) {
if (p instanceof Placeholder && p.index == idx) {
throw new Error(`Parent placeholder has same index: ${idx}`)
}
p = p.parent
}
}
}
export class Choice extends Marker {
private _index
constructor(index = 0) {
super()
this._index = index
}
public readonly options: Text[] = []
public appendChild(marker: Marker): this {
if (marker instanceof Text) {
marker.parent = this
this.options.push(marker)View on GitHub (pinned to 50e974d969)
Solutions
- Find the nested placeholder with the duplicate index in the snippet body.
- Renumber the inner placeholder to a unique index.
- Remove the redundant nesting if the text is identical.
- Validate snippets in tests using snippetManager.resolveSnippet or parser before shipping.
Example fix
// before
let snippet = 'class ${1:${1:Name}}'
// after
let snippet = 'class ${1:${2:Name}}' Defensive patterns
Strategy: validation
Validate before calling
function validateSnippet(body: string): boolean {
// quick textual check: no placeholder directly nested with same index
return !/\$\{(\d+):[^}]*\$\{\1:/.test(body)
} Type guard
function isSnippetString(s: unknown): s is string {
return typeof s === 'string' && !/\$\{(\d+):[^}]*\$\{\1:/.test(s)
} Try / catch
try {
snippetManager.resolveSnippet(body)
} catch (e) {
if (String(e.message).includes('Parent placeholder has same index')) fixDuplicateIndices(body)
} Prevention
- Never reuse the same index in nested placeholders.
- Run snippet strings through the parser in tests.
- Auto-renumber placeholders when generating snippets programmatically.
- Review snippets imported from other editors.
When it happens
Trigger: Parsing or programmatically building a snippet where a placeholder contains itself with the same index, e.g. '${1:${1:inner}}'.
Common situations: Hand-written or converted snippets (e.g. from other editors) with duplicated nested placeholder indices.
Related errors
- name and doComplete required for createSource
- Feature param could only starts with nvim and patch
- Invalid key ${name} of registerKeymap
- Invalid extension name: ${name}
- Invalid pattern ${filter.pattern.glob}!
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/c312e5c1ba834b3f.
Report an issue: GitHub.