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

  1. Ensure the argument is a string or a SnippetTextEdit/Snippet with a string value property.
  2. Fix the completion item construction to set value.
  3. Coerce or guard the value before calling the API.
  4. 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

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


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/7c9b31834f9bac9d. Report an issue: GitHub.