Eugeny/tabby · error · Error
Invalid code point
Error message
Invalid code point
What it means
Thrown by the utf8ToBytes() helper in the buffer polyfill (web/polyfills.buffer.ts), which implements Buffer.prototype.utf8Write. It encodes a JS string to UTF-8 bytes and rejects any code point >= 0x110000 (i.e. outside the valid Unicode range up to U+10FFFF). This is a defensive guard carried over from the feross/buffer polyfill.
Source
Thrown at web/polyfills.buffer.ts:204
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) {break}
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) {break}
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
// Create lookup table for `toString('hex')`
// See: https://github.com/feross/buffer/issues/219
const hexSliceLookupTable = (function () {
const alphabet = '0123456789abcdef'
const table = new Array(256)
for (let i = 0; i < 16; ++i) {
const i16 = i * 16
for (let j = 0; j < 16; ++j) {
table[i16 + j] = alphabet[i] + alphabet[j]
}
}
return table
})()View on GitHub (pinned to 14e2d60b9b)
Solutions
- Sanitize the input string before writing: strip or replace lone/out-of-range surrogates (e.g. U+FFFD replacement).
- Ensure you pass a real JS string (not a number/Buffer) to Buffer write methods that route through utf8Write.
- Update the buffer polyfill (and @types/node 'buffer') to a current version; this guard is standard and stable but depend on a maintained fork.
- Reproduce with a minimal input and confirm whether the data is genuinely corrupt upstream (logging the string's code units).
Example fix
// before
buf.write(maybeCorruptString, 0, len, 'utf8') // may throw 'Invalid code point'
// after: normalize the string first
const safe = maybeCorruptString.normalize('NFC').replace(/[�-�](?![�-�])|[^�-�][�-�]/g, '\uFFFD')
buf.write(safe, 0, safe.length, 'utf8') Defensive patterns
Strategy: validation
Validate before calling
function sanitizeForUtf8 (s: string): string {
// replace lone surrogates / out-of-range code units with U+FFFD
return s.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[^\uD800-\uDBFF][\uDC00-\uDFFF]/g, '\uFFFD')
}
const safe = sanitizeForUtf8(input)
buf.write(safe, 0, safe.length, 'utf8') Type guard
function isValidUtf8String (s: string): boolean {
// no lone surrogates -> cannot produce a code point >= 0x110000
return !/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[^\uD800-\uDBFF][\uDC00-\uDFFF]/.test(s)
} Try / catch
try {
buf.write(input, 0, input.length, 'utf8')
} catch (e) {
if (e.message === 'Invalid code point') {
buf.write(input.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[^\uD800-\uDBFF][\uDC00-\uDFFF]/g, '\uFFFD'), 0, input.length, 'utf8')
} else throw e
} Prevention
- Never pass non-string data to Buffer write methods expecting utf8.
- Sanitize strings arriving from untrusted/binary sources before encoding.
- Keep the buffer polyfill and 'buffer' types in sync after upgrades.
- Reproduce with the exact input to confirm upstream data corruption.
When it happens
Trigger: utf8ToBytes reaches the final else branch when, after surrogate-pair combining, codePoint is >= 0x110000. With well-formed JS strings and charCodeAt this is effectively unreachable (valid surrogate pairs max out at 0x10FFFF). It can be hit by feeding malformed input, a corrupted/mutated string, or by calling the internal helper directly with out-of-range numeric values instead of a real string.
Common situations: Corrupt binary data being treated as a string and then written via Buffer(buf).write(str, 0, length, 'utf8'); a polyfill version mismatch after a webpack/buffer upgrade; manually constructed string-like inputs with invalid surrogate sequences in edge-case locales; fuzzed or attacker-controlled text reaching a buffer write path.
AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12).
Data as JSON: /api/errors/d062d6a3337eccc2.
Report an issue: GitHub.