{"record":{"id":"32067566c9783be4","repo":"oven-sh/bun","slug":"second-buffer-was-modified","errorCode":null,"errorMessage":"Second buffer was modified","messagePattern":"Second buffer was modified","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"bench/snippets/buffer-concat.mjs","lineNumber":38,"sourceCode":"        : new Intl.NumberFormat(undefined, { unit: \"byte\", style: \"unit\" });\n\n  bench(\n    `Buffer.concat(${fmt.format(\n      Number((size > 1024 * 1024 ? size / 1024 / 1024 : size > 1024 ? size / 1024 : size).toFixed(2)),\n    )} x 3)`,\n    () => {\n      const result = Buffer.concat(buffers);\n      if (check) {\n        if (result.byteLength != size * 3) throw new Error(\"Wrong length\");\n        if (result[0] != 1) throw new Error(\"Wrong first byte\");\n        if (result[size] != 2) throw new Error(\"Wrong second byte\");\n        if (result[size * 2] != 3) throw new Error(\"Wrong third byte\");\n\n        result[0] = 10;\n        if (first[0] != 1) throw new Error(\"First buffer was modified\");\n\n        result[size] = 20;\n        if (second[0] != 2) throw new Error(\"Second buffer was modified\");\n\n        result[size * 2] = 30;\n        if (third[0] != 3) throw new Error(\"Third buffer was modified\");\n      }\n    },\n  );\n}\n\nconst chunk = Buffer.alloc(16);\nchunk.fill(\"3\");\nconst array = Array.from({ length: 100 }, () => chunk);\nbench(\"Buffer.concat 100 tiny chunks\", () => {\n  return Buffer.concat(array);\n});\n\nawait run();\n","sourceCodeStart":20,"sourceCodeEnd":55,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/bench/snippets/buffer-concat.mjs#L20-L55","documentation":"Correctness assertion inside the Buffer.concat benchmark (bench/snippets/buffer-concat.mjs). After Buffer.concat([first, second, third]) it writes 20 into result[size], the first byte that was copied from `second`, and requires second[0] to still be 2. Node semantics say concat must copy bytes into a brand-new Buffer, so this throws when the result shares memory with (aliases) an input buffer instead of being an independent copy.","triggerScenarios":"Buffer.concat returning a zero-copy view over one of its arguments, or a copy routine writing into the wrong region so that result[size] and second[0] resolve to the same address. Only reachable because the snippet hard-codes `check = true`, so every bench iteration verifies copy semantics.","commonSituations":"A regression in Bun's Buffer.concat implementation (JSC buffer bindings / node compat layer) that reuses input memory; running this snippet on a dev build while iterating on buffer fast paths; an optimization that special-cases concatenation of same-sized buffers.","solutions":["Reproduce outside the bench: concat two Buffers, write into result[size], and confirm second[0] changed — this proves memory aliasing","Run the Buffer test suite with your build: `bun bd test test/js/node/buffer` to find the failing conformance test","Inspect recent changes to Buffer.concat in the buffer implementation (src/runtime/node, JSC bindings) for a view/reuse fast path","If it reproduces on a released Bun, file an issue at github.com/oven-sh/bun with the minimal repro"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify Buffer.concat copies instead of aliasing (post-call check)\nfunction assertConcatCopies(buffers) {\n  const snapshots = buffers.map(b => b[0]);\n  const result = Buffer.concat(buffers);\n  let off = 0;\n  for (let i = 0; i < buffers.length; off += buffers[i].byteLength, i++) {\n    result[off] = result[off] ^ 0xff;\n    if (buffers[i][0] !== snapshots[i]) throw new Error('concat aliased input ' + i);\n  }\n  return result;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In tests that exercise buffer code paths, assert inputs are byte-identical before and after Buffer.concat plus a write to the result","Never assume a runtime might return a view from concat — Node semantics require a copy, so treat aliasing as a bug to report, not to code around","When optimizing Buffer.concat in Bun, keep this snippet in your verification loop: `bun bench/snippets/buffer-concat.mjs`"],"tags":["buffer","buffer-concat","benchmark","assertion","memory-aliasing","data-corruption"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}