-
Notifications
You must be signed in to change notification settings - Fork 695
Description
Panic message
# Rolldown Panic Report: `deferred_scan_data.rs:45` - "Should have resolved id: NotFound"
`@rolldown/browser@1.0.0-rc.2` panics during the Vite build process with:
thread 'tokio-runtime-worker' (2) panicked at
/home/runner/work/rolldown/rolldown/crates/rolldown/src/module_loader/deferred_scan_data.rs:45:12:
Should have resolved id: NotFound("/ecommerce/src/entry-client.js")
The panic occurs in the `defer_sync_scan_data` function when `resolver.resolve()` returns `NotFound` for a module that was **successfully resolved and scanned** during the initial scan phase. The `.expect("Should have resolved id")` on line 45 crashes instead of handling the error gracefully.
### Full console output (in order)
wasi-worker-browser.mjs:19 Rolldown panicked. This is a bug in Rolldown, not your code.
wasi-worker-browser.mjs:19 thread 'tokio-runtime-worker' (2) panicked at
/home/runner/work/rolldown/rolldown/crates/rolldown/src/module_loader/deferred_scan_data.rs:45:12:
wasi-worker-browser.mjs:19 Should have resolved id: NotFound("/ecommerce/src/entry-client.js")
wasi-worker-browser.mjs:19 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
wasi-worker-browser.mjs:19 Please report this issue at:
https://github.com/rolldown/rolldown/issues/new?template=panic_report.yml
wasi-threads.esm-bundler.js:257 worker (tid = 44) sent an error!
Uncaught RuntimeError: unreachable
### WASM stack trace
$wasi_thread_start @ 02a212da:1
ThreadMessageHandler._start @ wasi-threads.esm-bundler.js:890
ThreadMessageHandler.handleAfterLoad @ wasi-threads.esm-bundler.js:930
ThreadMessageHandler.handle @ wasi-threads.esm-bundler.js:847
MessageHandler.handle @ emnapi-core.esm-bundler.js:7609
globalThis.onmessage @ wasi-worker-browser.mjs:38
## Root Cause Analysis
Looking at [`deferred_scan_data.rs`](https://github.com/rolldown/rolldown/blob/main/crates/rolldown/src/module_loader/deferred_scan_data.rs), line 45:
let resolved_id = resolver
.resolve(None, source_id.as_str(), ImportKind::Import, normal.is_user_defined_entry)
.expect("Should have resolved id") // <-- LINE 45: panics here
.into();Reproduction
- Use
@rolldown/browser(WASM build) in a browser Web Worker environment with a custom WASI filesystem (VFS backed by OPFS + SharedArrayBuffer sync proxy) - Run a Vite build (
vite build) on a standard Vite + React + Tailwind CSS project - Vite calls
rolldown.rollup(options)thenbundle.generate() - The initial scan phase completes successfully — all modules are resolved and scanned (2600+ WASI filesystem operations succeed)
- During the bundling phase,
defer_sync_scan_dataruns and callsresolver.resolve(None, "/ecommerce/src/entry-client.js", ImportKind::Import, true) - The resolver returns
NotFoundeven though the file exists and was successfully resolved during the initial scan .expect("Should have resolved id")panics
System Info
## Environment
- **Package**: `@rolldown/browser@1.0.0-rc.2`
- **Runtime**: Browser (Chrome 133), running in a Web Worker with SharedArrayBuffer + WASI threads
- **Build tool**: Vite (using `@rolldown/browser` as the bundler via WASM)
- **Filesystem**: Custom WASI filesystem (VFS backed by OPFS + SharedArrayBuffer sync proxy)
- **Project**: Standard Vite + React + Tailwind CSS ecommerce template
- **Reproducibility**: 100% — happens on every build attemptAdditional context
The issue:
- During the initial scan phase,
/ecommerce/src/entry-client.jsis successfully resolved and scanned (confirmed by 2600+ successful WASI filesystem operations includingstatSyncon this exact file). - During
defer_sync_scan_data, the resolver tries to re-resolve the same file path withimporter: None. - This second resolution returns
NotFound, even though the file exists and was previously found. - The
.expect()panics instead of handling the error.
The resolver.resolve(None, source_id, ...) call passes None as the importer (first argument), which changes the resolution context compared to the original scan (where the importer was the parent module). The comment on lines 42-43 acknowledges this: "other params except source_id is not important, since we need package_json" — but this assumption can break when the importer context matters.
In our WASI filesystem environment, resolving an absolute path /ecommerce/src/entry-client.js with no importer context fails, even though the file physically exists.
Evidence the File Exists
The build logs show the file being successfully accessed multiple times before the panic:
[WASI-fs #581] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #685] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #695] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #696] lstatSync /ecommerce/src/entry-client.js ✓
[WASI-fs #971] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #1075] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #1085] statSync /ecommerce/src/entry-client.js {bigint} ✓
[WASI-fs #1086] lstatSync /ecommerce/src/entry-client.js ✓
[WASI-fs #1818] statSync /ecommerce/src/entry-client.js {bigint} ✓
All statSync calls returned successfully (no ENOENT). The file is a real .js file on the VFS, not a virtual module.
Suggested Fix
Replace the .expect() with graceful error handling:
// Before (panics):
let resolved_id = resolver
.resolve(None, source_id.as_str(), ImportKind::Import, normal.is_user_defined_entry)
.expect("Should have resolved id")
.into();
// After (graceful):
let Ok(resolved) = resolver
.resolve(None, source_id.as_str(), ImportKind::Import, normal.is_user_defined_entry)
else {
// If re-resolution fails, skip side-effect analysis for this module
continue;
};
let resolved_id = resolved.into();This matches the pattern used elsewhere in the same function (lines 24-31) where module_id_to_idx.get(), module_table.modules.get_mut(), and module.as_normal_mut() all use let Some(...) else { continue } for graceful fallback.
Related Issues
- #6569 — "should have idx" panic in the same
defer_sync_scan_datacode path (fixed, but the.expect()on line 45 was left intact) - #898 — WASI support tracking issue (documents filesystem and resolver limitations in WASM builds)
Build Context
The Vite build successfully completes:
- Config loading and bundling
- Vite initialization with rolldown
- Tailwind CSS oxide scanner (1200+ WASI filesystem calls)
- Rayon worker thread creation and scanning
- Module resolution for all project files
Then panics during the bundling phase in defer_sync_scan_data. The bundle.generate() call never returns, causing the build to hang indefinitely.