{"record":{"id":"7c9b31834f9bac9d","repo":"neoclide/coc.nvim","slug":"snippet-should-be-string-or-has-value-as-string","errorCode":null,"errorMessage":"Snippet should be string or has value as string","messagePattern":"Snippet should be string or has value as string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/snippets/util.ts","lineNumber":206,"sourceCode":"    if (i == n) {\n      let sc = range.start.character\n      let from = idx == 0 ? pos.character - sc : pos.character\n      newLines.unshift(line.slice(from))\n    } else {\n      newLines.unshift(line)\n    }\n  }\n  return newLines.join('\\n')\n}\n\nexport function toSnippetString(snippet: string | SnippetString | StringValue): string {\n  if (typeof snippet === 'string') {\n    return snippet\n  }\n  if (typeof snippet.value === 'string') {\n    return snippet.value\n  }\n  throw new TypeError(`Snippet should be string or has value as string`)\n}\n","sourceCodeStart":188,"sourceCodeEnd":208,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/snippets/util.ts#L188-L208","documentation":"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.","triggerScenarios":"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).","commonSituations":"Completion provider returns an item whose snippet value was never assigned; passing a resolved promise or parsed JSON object instead of the snippet string.","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."],"exampleFix":"// before\nsnippetManager.insertSnippet(item.snippet) // item.snippet is an object without value\n// after\nlet s = typeof item.snippet === 'string' ? item.snippet : item.snippet?.value\nif (typeof s !== 'string') return\nsnippetManager.insertSnippet(s)","handlingStrategy":"type-guard","validationCode":"if (typeof snippet !== 'string' && typeof snippet?.value !== 'string') return","typeGuard":"function isSnippetLike(s: unknown): s is string | { value: string } {\n  return typeof s === 'string' || (s != null && typeof (s as any).value === 'string')\n}","tryCatchPattern":"try {\n  let str = toSnippetString(snippet)\n} catch (e) {\n  if (e instanceof TypeError) logger.error('bad snippet argument', typeof snippet)\n}","preventionTips":["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."],"tags":["snippets","typeerror","invalid-argument"],"backgroundTag":"invalid-snippet-value","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}