neoclide/coc.nvim · error
Unsupported charset: ${encoding}
Error message
Unsupported charset: ${encoding} What it means
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.
Source
Thrown at src/model/fetch.ts:210
if (!Number.isFinite(maxResponseSize) || maxResponseSize <= 0) throw new Error('maxResponseSize must be a positive finite number')
opts.maxResponseSize = maxResponseSize
return opts
}
/**
* Extract and validate the charset parameter of a Content-Type header.
* Handles quoted values (charset="utf-8") and trailing parameters
* (charset=utf-8; format=flowed); throws for unsupported encodings.
*/
function parseCharset(contentType: string): BufferEncoding {
let match = /;\s*charset\s*=\s*"?([^";\s]+)"?/i.exec(contentType)
let encoding = match ? match[1] : 'utf8'
let lower = encoding.toLowerCase()
if (lower === 'iso-8859-1' || lower === 'latin-1') encoding = 'latin1'
else if (lower === 'utf-16' || lower === 'utf-16le' || lower === 'ucs-2' || lower === 'ucs2') encoding = 'utf16le'
else if (lower === 'us-ascii') encoding = 'ascii'
if (!Buffer.isEncoding(encoding)) {
throw new Error(`Unsupported charset: ${encoding}`)
}
return encoding
}
export function request(url: URL, data: any, opts: any, token?: CancellationToken, obj: any = {}): Promise<ResponseResult> {
let mod = getRequestModule(url)
return new Promise<ResponseResult>((resolve, reject) => {
let timer: NodeJS.Timeout
let settled = false
let req: any
let cancellation: { dispose(): void } | undefined
const cleanup = (): void => {
cancellation?.dispose()
cancellation = undefined
if (timer) clearTimeout(timer)
}
const succeed = (value: ResponseResult): void => {
if (settled) returnView on GitHub (pinned to 50e974d969)
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.
Example fix
// before
await fetch(url) // Content-Type: text/html; charset=gb2312 -> throws
// after
const res = await fetch(url, { buffer: true })
const text = iconv.decode(Buffer.from(res.content), 'gb2312') Defensive patterns
Strategy: try-catch
Validate before calling
const SUPPORTED = new Set(['utf8','utf-8','latin1','utf16le','ascii'])
function charsetSupported(contentType) {
const m = /charset=([\w-]+)/i.exec(contentType || '')
return !m || SUPPORTED.has(m[1].toLowerCase())
} Type guard
function hasSupportedCharset(ct: string | undefined): boolean {
const m = /charset=([^;]+)/i.exec(ct || '')
if (!m) return true
const enc = m[1].trim().replace(/['"]/g, '').toLowerCase()
return Buffer.isEncoding(enc) || ['iso-8859-1','utf-16','us-ascii'].includes(enc)
} Try / catch
try {
return await fetch(url)
} catch (e) {
if (/Unsupported charset/.test(e.message)) {
// fetch the raw bytes and decode with iconv-lite instead
return decodeWithIconv(url, 'gb2312')
}
throw e
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Legacy or non-English websites serving regional charsets (GBK, Shift_JIS, EUC-KR) without a BOM; misconfigured proxies injecting malformed charset parameters.
Related errors
- Request failed using proxy ${proxy.host}: ${err.message}
- Not valid protocol with ${urlInput}, should be http: or http
- maxResponseSize must be a positive finite number
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/4950824f98688e03.
Report an issue: GitHub.