Skip to content

bundler: allow relative FileMap keys without tripping absolute-path debug asserts - #32716

Closed
robobun wants to merge 4 commits into
mainfrom
farm/9c8ed586/filemap-relative-key-assert
Closed

bundler: allow relative FileMap keys without tripping absolute-path debug asserts#32716
robobun wants to merge 4 commits into
mainfrom
farm/9c8ed586/filemap-relative-key-assert

Conversation

@robobun

@robobun robobun commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Repro

await Bun.build({
  entrypoints: ["./e.js"],
  files: { "./e.js": ")" },
  target: "bun",
  throw: false,
});

Under a debug/ASAN build:

panic: assertion failed: crate::is_absolute(self.text)
<bun_paths::fs::Path>::assert_file_path_is_absolute  src/paths/lib.rs:961
<bun_bundler::bundle_v2::BundleV2>::enqueue_entry_item  src/bundler/bundle_v2.rs:2586
<bun_bundler::bundle_v2::BundleV2>::enqueue_entry_points_normal  src/bundler/bundle_v2.rs:2949

The invalid JS is incidental; any relative key used as an entry point panics. A second assertion in generate_isolated_hash (LinkerContext.rs:1780) fires for bare keys like "e.js" once the first one is past. Release builds are unaffected since both are debug_assert!.

Cause

Bun.build's files option stores user-supplied keys verbatim. The docs show relative keys as valid ("./src/generated.ts"), and release builds handle them correctly. Two CI-only assertions were too strict:

  • enqueue_entry_item asserts every file:-namespace path is absolute. FileMap::resolve returns the raw key in the file namespace, so relative keys trip it. The other two FileMap::resolve call sites (run_resolver, resolve_import_records) bypass enqueue_entry_item and never hit this.
  • generate_isolated_hash asserts pretty.ptr != text.ptr after path_with_pretty_initialized. For a bare relative key like "e.js", relative(top_level_dir, "e.js") yields "e.js" again, and dupe_alloc's index_of optimization re-aliases pretty to text at offset 0.

Fix

  • Skip assert_file_path_is_absolute in enqueue_entry_item when the path is a FileMap key (gated on CI_ASSERT so the contains lookup costs nothing in release).
  • Relax the generate_isolated_hash assertion to allow pretty.ptr == text.ptr for non-absolute text; absolute paths keep the original invariant.

Verification

bun bd test test/bundler/bundler_files.test.ts: 27 pass (4 new subprocess tests covering "./e.js", "e.js", "./src/e.js", and the fuzzer's parse-error input). With src/ reverted, all 4 new tests fail on the panic.

…ebug asserts

Bun.build's `files` option accepts user-supplied keys that may be
relative (the docs show "./src/generated.ts"). Two debug assertions
assumed file-namespace paths are always absolute:

- enqueue_entry_item asserted every file-namespace path is absolute,
  but FileMap keys are lookup identities, not real fs paths. Skip the
  assertion when the path is a FileMap key.
- generate_isolated_hash asserted path_with_pretty_initialized always
  yields pretty.ptr != text.ptr, but for a bare relative key like
  "e.js" the computed pretty equals text and dupe_alloc aliases them.
  Relax the assertion to allow this for non-absolute text.

Release builds were unaffected (both are debug_assert); only CI_ASSERT
builds panicked.

Fuzzer repro:
  Bun.build({entrypoints:["./e.js"], files:{"./e.js": ")"}, throw:false})
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8e8316dc-8ffd-4740-870f-3791ec2287d2

📥 Commits

Reviewing files that changed from the base of the PR and between a074ce6 and 0791891.

📒 Files selected for processing (1)
  • test/bundler/bundler_files.test.ts

Walkthrough

The bundler now conditions absolute-path assertions on FileMap-backed entry keys and relaxes pretty-path aliasing checks for equal text/pretty paths. Tests add subprocess coverage for relative-key Bun.build entries and parse-error failure reporting.

Changes

Relative-key bundler assertions

Layer / File(s) Summary
Entry-item path assertion
src/bundler/bundle_v2.rs
BundleV2::enqueue_entry_item only performs the absolute-path assertion in CI when file_map contains the entry key.
Isolated-hash aliasing
src/bundler/LinkerContext.rs
generate_isolated_hash allows source.path.pretty to alias source.path.text when they match and keeps the absolute-path restriction in that case.
Relative-key build regressions
test/bundler/bundler_files.test.ts
The test file imports bunEnv and bunExe and adds subprocess cases for relative-key Bun.build entries and parse-error failure reporting.

Possibly related PRs

  • oven-sh/bun#31647: Touches the same LinkerContext::generate_isolated_hash text-versus-pretty path aliasing logic and related debug assertion behavior.

Suggested reviewers

  • Jarred-Sumner
  • alii
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: allowing relative FileMap keys without hitting debug absolute-path asserts.
Description check ✅ Passed The description covers repro, cause, fix, and verification, matching the template's intent despite different headings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 7:58 PM PT - Jun 25th, 2026

@robobun, your commit 0791891 has 3 failures in Build #64783 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 32716

That installs a local version of the PR into your bun-32716 executable, so you can run:

bun-32716 --bun

Comment thread test/bundler/bundler_files.test.ts Outdated
Comment thread test/bundler/bundler_files.test.ts Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — both prior nits addressed; debug-assert-only relaxations with regression tests.

Extended reasoning...

Overview

This PR relaxes two over-strict debug assertions in the bundler that fired when Bun.build's files option was given relative keys (e.g. "./e.js") as entry points — a documented and release-correct usage. Touches:

  • src/bundler/bundle_v2.rs (+7/-1): gate assert_file_path_is_absolute in enqueue_entry_item so it skips paths that are FileMap keys; the file_map.contains() lookup is itself gated on CI_ASSERT so it dead-code-eliminates in release.
  • src/bundler/LinkerContext.rs (+6/-4): relax the pretty.ptr != text.ptr debug_assert! in generate_isolated_hash to allow aliasing when text is non-absolute (the original invariant for absolute paths is preserved via || !is_absolute(text)).
  • test/bundler/bundler_files.test.ts (+63/-1): four new subprocess regression tests covering "./e.js", "e.js", "./src/e.js", and the fuzzer's parse-error input.

Security risks

None. Both source changes touch only debug_assert! / CI_ASSERT-gated code paths and have zero effect on release builds. No auth, crypto, fs, or network surface is involved.

Level of scrutiny

Low. Release behaviour is unchanged by construction — assert_file_path_is_absolute (src/paths/lib.rs:960) is already a no-op outside CI_ASSERT, and debug_assert! compiles out in release. The relaxations are principled and narrow: the bundle_v2.rs change only exempts paths that are verifiably FileMap keys, and the LinkerContext.rs change keeps the original invariant for absolute paths. The PR description's root-cause analysis (dupe_alloc's index_of re-aliasing pretty→text at offset 0 for bare relative keys) is consistent with the code.

Other factors

  • Both of my earlier nits (4-line comment, sequential subprocess tests) were addressed in 89a51df and 0791891 respectively, and both threads are resolved.
  • No CODEOWNERS coverage for src/bundler/ or test/bundler/.
  • The bug-hunting system found no issues.
  • Tests run in subprocesses specifically so a regression panic fails the test rather than killing the runner — appropriate for assertion-panic coverage.

@robobun

robobun commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

CI status: test/bundler/bundler_files.test.ts passes on all lanes. The remaining red is test/napi/napi.test.ts (napi_is_arraybuffer) on Windows 2019 x64, a CRLF line-ending mismatch introduced by #32629 that also fails on other branches (e.g. build 64780). Not touched by this diff. Ready for review.

@robobun

robobun commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator Author

#38650 takes a different approach to the same assertion failure: it resolves relative files keys against the cwd when the options are parsed, so the keys become absolute paths (which also makes the documented "./src/config.ts" override and "./src/generated.ts" virtual-file examples work; they are no-ops today because import lookups compare absolute paths). If that lands, the two assertions this PR relaxes hold again for files keys, so the two PRs are alternatives rather than complements.

@robobun

robobun commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favour of #38650, which fixes the same assertion failure from the other side: relative files keys are resolved against the cwd when they are inserted, so the two assertions this PR relaxes hold as written. That also makes the documented "./src/config.ts" override and "./src/generated.ts" virtual-file examples work; on main they fail to resolve, and they would still fail with this PR since it only touches the assertions.

The cases covered here ("./e.js", "e.js" and "./src/e.js" as entry points, and the parse-error input) pass against a debug build of #38650, and the parse-error case was added to its test file.

@robobun robobun closed this Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant