denoland/deno · error · RangeError
Buffer size must be a multiple of 16-bits
Error message
Buffer size must be a multiple of 16-bits
What it means
Buffer.prototype.swap16() reverses bytes in place in 2-byte pairs (a 16-bit endianness flip, e.g. UTF-16LE <-> UTF-16BE). A buffer with an odd byte length cannot be divided into 2-byte pairs, so the method throws a plain RangeError before modifying any bytes. Same contract as Node's lib/internal/buffer.js.
Source
Thrown at ext/node/polyfills/internal/buffer.mjs:671
const ops = getEncodingOps(encoding);
if (ops === undefined) {
return (mustMatch ? -1 : byteLengthUtf8(string));
}
return ops.byteLength(string);
}
Buffer.byteLength = byteLength;
function swap(b, n, m) {
const i = b[n];
b[n] = b[m];
b[m] = i;
}
Buffer.prototype.swap16 = function swap16() {
const len = this.length;
if (len % 2 !== 0) {
throw new RangeError("Buffer size must be a multiple of 16-bits");
}
for (let i = 0; i < len; i += 2) {
swap(this, i, i + 1);
}
return this;
};
Buffer.prototype.swap32 = function swap32() {
const len = this.length;
if (len % 4 !== 0) {
throw new RangeError("Buffer size must be a multiple of 32-bits");
}
for (let i = 0; i < len; i += 4) {
swap(this, i, i + 3);
swap(this, i + 1, i + 2);
}
return this;
};View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Check alignment first and handle the trailing byte explicitly (report truncation or pad)
- Trim to the largest even boundary when the last byte is padding: buf.subarray(0, buf.length - buf.length % 2).swap16()
- Validate the source length (file size, Content-Length, protocol length field) before endian conversion - odd length usually means truncated input
- Pad deliberately when the format expects it: Buffer.concat([buf, Buffer.alloc(1)]).swap16()
Example fix
// before
const buf = Buffer.from('abc'); // 3 bytes
buf.swap16(); // RangeError: Buffer size must be a multiple of 16-bits
// after
if (buf.length % 2 !== 0) throw new Error('truncated UTF-16 payload');
buf.swap16(); Defensive patterns
Strategy: validation
Validate before calling
function swap16Safe(buf) {
if (buf.length % 2 !== 0) {
throw new RangeError(`expected even byte length, got ${buf.length}`);
}
return buf.swap16();
} Try / catch
try {
buf.swap16();
} catch (e) {
if (e instanceof RangeError) { /* record truncation, trim to even boundary, or refetch data */ }
else throw e;
} Prevention
- Validate payload length against the protocol unit size before endian swaps
- Centralize UTF-16 decode helpers that assert even length with a descriptive error
- Test with odd-length inputs to surface truncation early
When it happens
Trigger: buf.swap16() when buf.length % 2 !== 0, e.g. Buffer.from('abc').swap16() (3 bytes) or a 101-byte network frame parsed as UTF-16.
Common situations: Decoding UTF-16 files with a truncated final code unit (broken download, wrong length from a header); odd-length test fixtures; an off-by-one in slicing that leaves one stray byte before conversion.
Related errors
- Buffer size must be a multiple of 32-bits
- Buffer size must be a multiple of 64-bits
- ERR_STRING_TOO_LONG
- The value "${length}" is invalid for option "size"
- Attempt to allocate Buffer larger than maximum size: 0x${kMa
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/27b6b67539c0a9b4.
Report an issue: GitHub.