Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/bun.js/ModuleLoader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2554,12 +2554,18 @@ pub const RuntimeTranspilerStore = struct {
}

if (strings.hasPrefixComptime(import_record.path.text, "bun:")) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";
import_record.is_external_without_side_effects = true;
// Validate and strip the bun: prefix for builtin modules.
// Invalid modules (e.g., "bun:invalid") are left unchanged so the
// resolver can report an error with the full "bun:invalid" name instead
// of the confusing "Cannot find package 'invalid'".
if (HardcodedModule.map.has(import_record.path.text)) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";
import_record.is_external_without_side_effects = true;

if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
}
}
}
}
Expand Down
22 changes: 13 additions & 9 deletions src/bundler/bundle_v2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3175,17 +3175,21 @@ pub const BundleV2 = struct {
}

if (strings.hasPrefixComptime(import_record.path.text, "bun:")) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";
import_record.source_index = Index.invalid;
import_record.is_external_without_side_effects = true;
// Validate and strip the bun: prefix for builtin modules.
// Invalid modules are left unchanged for better error messages.
if (jsc.ModuleLoader.HardcodedModule.map.has(import_record.path.text)) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";
import_record.source_index = Index.invalid;
import_record.is_external_without_side_effects = true;

if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
}
if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
}

// don't link bun
continue;
// don't link bun
continue;
}
}
}

Expand Down
18 changes: 11 additions & 7 deletions src/linker.zig
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,19 @@ pub const Linker = struct {
}

if (strings.hasPrefixComptime(import_record.path.text, "bun:")) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";
// Validate and strip the bun: prefix for builtin modules.
// Invalid modules are left unchanged for better error messages.
if (jsc.ModuleLoader.HardcodedModule.map.has(import_record.path.text)) {
import_record.path = Fs.Path.init(import_record.path.text["bun:".len..]);
import_record.path.namespace = "bun";

if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
}
if (strings.eqlComptime(import_record.path.text, "test")) {
import_record.tag = .bun_test;
}

// don't link bun
continue;
// don't link bun
continue;
}
}

// Resolve dynamic imports lazily for perf
Expand Down
22 changes: 22 additions & 0 deletions test/regression/issue/invalid-bun-module-prefix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDirWithFiles } from "harness";

test("invalid bun: module should preserve prefix in error", async () => {
const dir = tempDirWithFiles("bun-invalid-module", {
"test.js": 'import foo from "bun:apskdaposkdpok"',
});

const { stderr } = Bun.spawnSync({
cmd: [bunExe(), "test.js"],
cwd: dir,
env: bunEnv,
stderr: "pipe",
});

const output = stderr.toString();
// Error should mention "bun:apskdaposkdpok" not just "apskdaposkdpok"
expect(output).toContain("bun:apskdaposkdpok");
// The error could be "Cannot find package" or "Cannot resolve invalid URL"
// The key is that it shows the full "bun:..." prefix
expect(output).toMatch(/Cannot (find package|resolve invalid URL)/);
});