oven-sh/bun · critical · Error

Third buffer was modified

Error message

Third buffer was modified

What it means

Same copy-semantics assertion as its siblings in bench/snippets/buffer-concat.mjs, but for the last input: after Buffer.concat([first, second, third]) it writes 30 into result[size * 2] and requires third[0] to remain 3. It throws when the concat result's tail region aliases the `third` buffer's memory, i.e. concat did not produce an independent copy.

Source

Thrown at bench/snippets/buffer-concat.mjs:41

    `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

  1. Isolate with a 3-buffer concat of distinct fill values and write result[result.length - 1] to see if third changes
  2. Run `bun bd test test/js/node/buffer` to catch the conformance failure
  3. Review Buffer.concat changes for accidental view-return or in-place writes into an argument
  4. Report to oven-sh/bun with the minimal aliasing repro if it reproduces in a release build
Defensive patterns

Strategy: validation

Validate before calling

// tail-region aliasing check: write the last byte, verify the last input
const result = Buffer.concat([first, second, third]);
result[result.length - 1] ^= 0xff;
if (third[0] !== 3) throw new Error('concat aliased the tail input');

Prevention

When it happens

Trigger: Buffer.concat reusing the last argument's backing memory (a common zero-copy temptation since the tail of the result aligns with it), or an off-by-one/region bug in the copy loop that makes result[size * 2] and third[0] the same byte. The check runs on every iteration because `check` is hard-coded true.

Common situations: Regressions in Bun's Buffer.concat tail-copy path; dev builds while optimizing large (16 MB) concatenations; comparing aliasing behavior against Node, which always copies.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/d771cd2fd298abf8. Report an issue: GitHub.