oven-sh/bun · critical · Error
Second buffer was modified
Error message
Second buffer was modified
What it means
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.
Source
Thrown at bench/snippets/buffer-concat.mjs:38
: new Intl.NumberFormat(undefined, { unit: "byte", style: "unit" });
bench(
`Buffer.concat(${fmt.format(
Number((size > 1024 * 1024 ? size / 1024 / 1024 : size > 1024 ? size / 1024 : size).toFixed(2)),
)} x 3)`,
() => {
const result = Buffer.concat(buffers);
if (check) {
if (result.byteLength != size * 3) throw new Error("Wrong length");
if (result[0] != 1) throw new Error("Wrong first byte");
if (result[size] != 2) throw new Error("Wrong second byte");
if (result[size * 2] != 3) throw new Error("Wrong third byte");
result[0] = 10;
if (first[0] != 1) throw new Error("First buffer was modified");
result[size] = 20;
if (second[0] != 2) throw new Error("Second buffer was modified");
result[size * 2] = 30;
if (third[0] != 3) throw new Error("Third buffer was modified");
}
},
);
}
const chunk = Buffer.alloc(16);
chunk.fill("3");
const array = Array.from({ length: 100 }, () => chunk);
bench("Buffer.concat 100 tiny chunks", () => {
return Buffer.concat(array);
});
await run();
View on GitHub (pinned to 8c5296ac45)
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
Defensive patterns
Strategy: validation
Validate before calling
// verify Buffer.concat copies instead of aliasing (post-call check)
function assertConcatCopies(buffers) {
const snapshots = buffers.map(b => b[0]);
const result = Buffer.concat(buffers);
let off = 0;
for (let i = 0; i < buffers.length; off += buffers[i].byteLength, i++) {
result[off] = result[off] ^ 0xff;
if (buffers[i][0] !== snapshots[i]) throw new Error('concat aliased input ' + i);
}
return result;
} Prevention
- 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`
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Third buffer was modified
- bad result
- Expected ${expected} to be ${equal} for ${description}
- bad
- Please run `make compile-ffi-test` to compile the ffi test l
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/32067566c9783be4.
Report an issue: GitHub.