Fix bundler assertion failure (#22387)

### What does this PR do?

Fixes "panic: Internal assertion failure: total_insertions (N) !=
output_files.items.len (N)"

Fixes #22151
This commit is contained in:
Zack Radisic
2025-09-03 21:18:00 -07:00
committed by GitHub
parent b79bbfe289
commit 0bcb3137d3
3 changed files with 78 additions and 17 deletions

View File

@@ -60,6 +60,8 @@ pub fn init(
pub fn take(this: *@This()) std.ArrayList(options.OutputFile) {
// TODO: should this return an error
bun.assertf(this.total_insertions == this.output_files.items.len, "total_insertions ({d}) != output_files.items.len ({d})", .{ this.total_insertions, this.output_files.items.len });
// Set the length just in case so the list doesn't have undefined memory
this.output_files.items.len = this.total_insertions;
const list = this.output_files;
this.output_files = std.ArrayList(options.OutputFile).init(bun.default_allocator);
return list;
@@ -78,21 +80,14 @@ pub fn calculateOutputFileListCapacity(c: *const bun.bundle_v2.LinkerContext, ch
const bytecode_count = if (c.options.generate_bytecode_cache) bytecode_count: {
var bytecode_count: usize = 0;
for (chunks) |*chunk| {
// TODO: this was the original logic, but it seems like it is
// incorrect / does unnecessary work? Leaving it here just in-case,
// as it moved from a different file and is not git blame-able.
//
// const loader: Loader = if (chunk.entry_point.is_entry_point)
// c.parse_graph.input_files.items(.loader)[
// chunk.entry_point.source_index
// ]
// else
// .js;
// if (loader.isJavaScriptLike()) {
// bytecode_count += 1;
// }
const loader: bun.options.Loader = if (chunk.entry_point.is_entry_point)
c.parse_graph.input_files.items(.loader)[
chunk.entry_point.source_index
]
else
.js;
if (chunk.content == .javascript) {
if (chunk.content == .javascript and loader.isJavaScriptLike()) {
bytecode_count += 1;
}
}

View File

@@ -427,7 +427,7 @@ pub fn generateChunksInParallel(
else
.js;
if (loader.isJavaScriptLike()) {
if (chunk.content == .javascript and loader.isJavaScriptLike()) {
jsc.VirtualMachine.is_bundler_thread_for_bytecode_cache = true;
jsc.initialize(false);
var fdpath: bun.PathBuffer = undefined;

View File

@@ -1,7 +1,7 @@
import { Database } from "bun:sqlite";
import { describe, expect } from "bun:test";
import { describe, expect, test } from "bun:test";
import { rmSync } from "fs";
import { isWindows } from "harness";
import { bunEnv, bunExe, isWindows, tempDirWithFiles } from "harness";
import { itBundled } from "./expectBundled";
describe("bundler", () => {
@@ -665,4 +665,70 @@ error: Hello World`,
},
],
});
test("does not crash", async () => {
const dir = tempDirWithFiles("bundler-compile-shadcn", {
"frontend.tsx": `console.log("Hello, world!");`,
"index.html": `<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bun + React</title>
<script type="module" src="./frontend.tsx" async></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
`,
"index.tsx": `import { serve } from "bun";
import index from "./index.html";
const server = serve({
routes: {
// Serve index.html for all unmatched routes.
"/*": index,
"/api/hello": {
async GET(req) {
return Response.json({
message: "Hello, world!",
method: "GET",
});
},
async PUT(req) {
return Response.json({
message: "Hello, world!",
method: "PUT",
});
},
},
"/api/hello/:name": async req => {
const name = req.params.name;
return Response.json({
message: "LOL",
});
},
},
development: process.env.NODE_ENV !== "production" && {
// Enable browser hot reloading in development
hmr: true,
// Echo console logs from the browser to the server
console: true,
},
});
`,
});
// Step 2: Run bun build with compile, minify, sourcemap, and bytecode
await Bun.$`${bunExe()} build ./index.tsx --compile --minify --sourcemap --bytecode`
.cwd(dir)
.env(bunEnv)
.throws(true);
});
});