neoclide/coc.nvim · error · TypeError
Snippet should be string or has value as string
Error message
Snippet should be string or has value as string
What it means
toSnippetString converts a snippet argument into its string body. It accepts a plain string or a Snippet object with a string value; anything else (undefined, wrong type, or an object lacking .value) throws this TypeError. Called from inserted, snippetStr, _insertSnippetEdits and textEdits.
Source
Thrown at src/snippets/util.ts:206
if (i == n) {
let sc = range.start.character
let from = idx == 0 ? pos.character - sc : pos.character
newLines.unshift(line.slice(from))
} else {
newLines.unshift(line)
}
}
return newLines.join('\n')
}
export function toSnippetString(snippet: string | SnippetString | StringValue): string {
if (typeof snippet === 'string') {
return snippet
}
if (typeof snippet.value === 'string') {
return snippet.value
}
throw new TypeError(`Snippet should be string or has value as string`)
}
View on GitHub (pinned to 50e974d969)
Solutions
- Ensure the argument is a string or a SnippetTextEdit/Snippet with a string value property.
- Fix the completion item construction to set value.
- Coerce or guard the value before calling the API.
- Log the actual argument type to find where the wrong object originates.
Example fix
// before snippetManager.insertSnippet(item.snippet) // item.snippet is an object without value // after let s = typeof item.snippet === 'string' ? item.snippet : item.snippet?.value if (typeof s !== 'string') return snippetManager.insertSnippet(s)
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof snippet !== 'string' && typeof snippet?.value !== 'string') return
Type guard
function isSnippetLike(s: unknown): s is string | { value: string } {
return typeof s === 'string' || (s != null && typeof (s as any).value === 'string')
} Try / catch
try {
let str = toSnippetString(snippet)
} catch (e) {
if (e instanceof TypeError) logger.error('bad snippet argument', typeof snippet)
} Prevention
- Always set the value field on completion items that carry snippets.
- Narrow unknown values with isSnippetLike before insertSnippet calls.
- Check completion provider return shapes in tests.
- Avoid passing raw API objects where a string is expected.
When it happens
Trigger: Passing undefined/null, a non-snippet object, or a Snippet whose value is not a string to snippet insertion APIs (e.g. snippetManager.insertSnippet or completion item resolution).
Common situations: Completion provider returns an item whose snippet value was never assigned; passing a resolved promise or parsed JSON object instead of the snippet string.
Related errors
- select kind "${kind}" not supported
- Service ${id} not found
- Parent placeholder has same index: ${idx}
- Unable to find parent marker in range ${JSON.stringify(range
- pattern \z not supported
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/7c9b31834f9bac9d.
Report an issue: GitHub.