{"record":{"id":"8f11f2a5a8bbf6b7","repo":"denoland/deno","slug":"buffer-size-must-be-a-multiple-of-64-bits","errorCode":null,"errorMessage":"Buffer size must be a multiple of 64-bits","messagePattern":"Buffer size must be a multiple of 64-bits","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/buffer.mjs","lineNumber":694,"sourceCode":"  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);\n  }\n  return this;\n};\n\nfunction decodeUtf8(buffer, start, end) {\n  return op_node_encoding_slice(\n    buffer,\n    start,\n    end,\n    0,\n  );\n}","sourceCodeStart":676,"sourceCodeEnd":712,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/buffer.mjs#L676-L712","documentation":"Buffer.prototype.swap64() reverses bytes in place in 8-byte groups (64-bit endianness flip used for doubles, BigInt64, f64 arrays). If the byte length is not a multiple of 8 the buffer cannot be split into whole 64-bit words, so a plain RangeError is thrown before any modification. Same as Node.","triggerScenarios":"buf.swap64() when buf.length % 8 !== 0, e.g. Buffer.alloc(12).swap64() or a 20-byte payload of f64 values after a partial socket read.","commonSituations":"Converting arrays of 64-bit doubles or BigInt64 between endian formats; binary protocols with 8-byte fields where a short read left length % 8 != 0; buffers assembled from chunks whose total length was never re-validated.","solutions":["Check length % 8 === 0 first and report the remainder as truncation","Trim to an 8-byte boundary for padded formats: buf.subarray(0, buf.length - buf.length % 8).swap64()","Re-check the framing arithmetic that produced the buffer - a wrong length prefix is the usual root cause","Pad explicitly to the next multiple of 8 when the format requires it"],"exampleFix":"// before\nconst buf = Buffer.alloc(12);\nbuf.swap64(); // RangeError: Buffer size must be a multiple of 64-bits\n\n// after\nconst usable = buf.length - (buf.length % 8);\nbuf.subarray(0, usable).swap64(); // swaps the first 8 bytes","handlingStrategy":"validation","validationCode":"function swap64Safe(buf) {\n  if (buf.length % 8 !== 0) {\n    throw new RangeError(`expected byte length divisible by 8, got ${buf.length}`);\n  }\n  return buf.swap64();\n}","typeGuard":null,"tryCatchPattern":"try {\n  buf.swap64();\n} catch (e) {\n  if (e instanceof RangeError) { /* trim to 8-byte boundary or refetch the record */ }\n  else throw e;\n}","preventionTips":["Re-validate total length after assembling buffers from chunks","Double-check length prefixes before converting 64-bit fields","Add alignment assertions to binary protocol test fixtures"],"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"}