{"record":{"id":"332364237ab29eef","repo":"denoland/deno","slug":"buffer-size-must-be-a-multiple-of-32-bits","errorCode":null,"errorMessage":"Buffer size must be a multiple of 32-bits","messagePattern":"Buffer size must be a multiple of 32-bits","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/buffer.mjs","lineNumber":682,"sourceCode":"  b[n] = b[m];\n  b[m] = i;\n}\n\nBuffer.prototype.swap16 = function swap16() {\n  const len = this.length;\n  if (len % 2 !== 0) {\n    throw new RangeError(\"Buffer size must be a multiple of 16-bits\");\n  }\n  for (let i = 0; i < len; i += 2) {\n    swap(this, i, i + 1);\n  }\n  return this;\n};\n\nBuffer.prototype.swap32 = function swap32() {\n  const len = this.length;\n  if (len % 4 !== 0) {\n    throw new RangeError(\"Buffer size must be a multiple of 32-bits\");\n  }\n  for (let i = 0; i < len; i += 4) {\n    swap(this, i, i + 3);\n    swap(this, i + 1, i + 2);\n  }\n  return this;\n};\n\nBuffer.prototype.swap64 = function swap64() {\n  const len = this.length;\n  if (len % 8 !== 0) {\n    throw new RangeError(\"Buffer size must be a multiple of 64-bits\");\n  }\n  for (let i = 0; i < len; i += 8) {\n    swap(this, i, i + 7);\n    swap(this, i + 1, i + 6);\n    swap(this, i + 2, i + 5);\n    swap(this, i + 3, i + 4);","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/buffer.mjs#L664-L700","documentation":"Buffer.prototype.swap32() reverses bytes in place in 4-byte groups (32-bit endianness flip used for int32/float32 data). If the buffer's byte length is not a multiple of 4 it cannot be split into whole 32-bit words, so a plain RangeError is thrown before any byte is touched. Behavior matches Node exactly.","triggerScenarios":"buf.swap32() when buf.length % 4 !== 0, e.g. Buffer.from([1,2,3,4,5]).swap32() (5 bytes) or a 10-byte record body read from a socket.","commonSituations":"Parsing fixed-width binary records (int32/float32 arrays, IP headers, WAV samples) where a partial read left the length misaligned; test buffers built from arbitrary strings; slicing errors that drop bytes from a record.","solutions":["Verify length % 4 === 0 before swapping; treat a remainder as a truncated-read error","Trim to a 4-byte boundary when trailing bytes are padding: buf.subarray(0, buf.length - buf.length % 4).swap32()","Log the actual length at the read site - misalignment usually means the framing/length prefix was misparsed","Pad to a multiple of 4 when the consumer format requires it"],"exampleFix":"// before\nconst buf = Buffer.from('abcde'); // 5 bytes\nbuf.swap32(); // RangeError: Buffer size must be a multiple of 32-bits\n\n// after\nconst usable = buf.length - (buf.length % 4);\nbuf.subarray(0, usable).swap32();","handlingStrategy":"validation","validationCode":"function swap32Safe(buf) {\n  if (buf.length % 4 !== 0) {\n    throw new RangeError(`expected byte length divisible by 4, got ${buf.length}`);\n  }\n  return buf.swap32();\n}","typeGuard":null,"tryCatchPattern":"try {\n  buf.swap32();\n} catch (e) {\n  if (e instanceof RangeError) { /* trim to 4-byte boundary or refetch the record */ }\n  else throw e;\n}","preventionTips":["Assert record-size alignment right after every binary read","Log actual buffer lengths at parse sites to catch framing bugs","Keep binary parsing helpers in one module so alignment checks are not duplicated"],"tags":["buffer","endianness","range-error","binary-data"],"backgroundTag":"buffer-length-misaligned","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}