{"record":{"id":"4950824f98688e03","repo":"neoclide/coc.nvim","slug":"unsupported-charset-encoding","errorCode":null,"errorMessage":"Unsupported charset: ${encoding}","messagePattern":"Unsupported charset: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/model/fetch.ts","lineNumber":210,"sourceCode":"  if (!Number.isFinite(maxResponseSize) || maxResponseSize <= 0) throw new Error('maxResponseSize must be a positive finite number')\n  opts.maxResponseSize = maxResponseSize\n  return opts\n}\n\n/**\n * Extract and validate the charset parameter of a Content-Type header.\n * Handles quoted values (charset=\"utf-8\") and trailing parameters\n * (charset=utf-8; format=flowed); throws for unsupported encodings.\n */\nfunction parseCharset(contentType: string): BufferEncoding {\n  let match = /;\\s*charset\\s*=\\s*\"?([^\";\\s]+)\"?/i.exec(contentType)\n  let encoding = match ? match[1] : 'utf8'\n  let lower = encoding.toLowerCase()\n  if (lower === 'iso-8859-1' || lower === 'latin-1') encoding = 'latin1'\n  else if (lower === 'utf-16' || lower === 'utf-16le' || lower === 'ucs-2' || lower === 'ucs2') encoding = 'utf16le'\n  else if (lower === 'us-ascii') encoding = 'ascii'\n  if (!Buffer.isEncoding(encoding)) {\n    throw new Error(`Unsupported charset: ${encoding}`)\n  }\n  return encoding\n}\n\nexport function request(url: URL, data: any, opts: any, token?: CancellationToken, obj: any = {}): Promise<ResponseResult> {\n  let mod = getRequestModule(url)\n  return new Promise<ResponseResult>((resolve, reject) => {\n    let timer: NodeJS.Timeout\n    let settled = false\n    let req: any\n    let cancellation: { dispose(): void } | undefined\n    const cleanup = (): void => {\n      cancellation?.dispose()\n      cancellation = undefined\n      if (timer) clearTimeout(timer)\n    }\n    const succeed = (value: ResponseResult): void => {\n      if (settled) return","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/model/fetch.ts#L192-L228","documentation":"parseCharset extracts the charset parameter from a Content-Type header and maps common aliases (iso-8859-1, utf-16, us-ascii, etc.) to Node Buffer encodings. If the resulting name is not a supported Buffer encoding (Buffer.isEncoding fails), it throws 'Unsupported charset: <encoding>' instead of producing mojibake or crashing later during decode.","triggerScenarios":"A server responds with Content-Type: text/html; charset=gb2312, charset=windows-1252, charset=iso-8859-2, or an empty/typo'd charset value like charset=''; the unmapped name fails Buffer.isEncoding.","commonSituations":"Legacy or non-English websites serving regional charsets (GBK, Shift_JIS, EUC-KR) without a BOM; misconfigured proxies injecting malformed charset parameters.","solutions":["Fix the server/proxy to send a supported charset (utf-8, latin1, utf16le, ascii).","Fetch the body as buffer (options.buffer) and decode it yourself with iconv-lite for non-Node encodings.","If you control the request URL, prefer an endpoint that returns UTF-8."],"exampleFix":"// before\nawait fetch(url) // Content-Type: text/html; charset=gb2312 -> throws\n// after\nconst res = await fetch(url, { buffer: true })\nconst text = iconv.decode(Buffer.from(res.content), 'gb2312')","handlingStrategy":"try-catch","validationCode":"const SUPPORTED = new Set(['utf8','utf-8','latin1','utf16le','ascii'])\nfunction charsetSupported(contentType) {\n  const m = /charset=([\\w-]+)/i.exec(contentType || '')\n  return !m || SUPPORTED.has(m[1].toLowerCase())\n}","typeGuard":"function hasSupportedCharset(ct: string | undefined): boolean {\n  const m = /charset=([^;]+)/i.exec(ct || '')\n  if (!m) return true\n  const enc = m[1].trim().replace(/['\"]/g, '').toLowerCase()\n  return Buffer.isEncoding(enc) || ['iso-8859-1','utf-16','us-ascii'].includes(enc)\n}","tryCatchPattern":"try {\n  return await fetch(url)\n} catch (e) {\n  if (/Unsupported charset/.test(e.message)) {\n    // fetch the raw bytes and decode with iconv-lite instead\n    return decodeWithIconv(url, 'gb2312')\n  }\n  throw e\n}","preventionTips":["Prefer endpoints that serve UTF-8 with an explicit charset=utf-8 header.","Use options.buffer and decode manually with iconv-lite for legacy encodings (GBK, Shift_JIS).","Probe the Content-Type header (HEAD request) before fetching text from legacy servers."],"tags":["network","encoding","charset","http"],"backgroundTag":"unsupported-charset","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}