rolldown/rolldown · error
should have common dir for entries
Error message
should have common dir for entries
What it means
For external module ids that need path renormalization, rolldown computes the common directory of all user-defined entries via `commondir::common_dir` and makes the external module path relative to it. `common_dir` returns `None` when no common directory exists (e.g. paths on different roots/drives or an empty entry list), and this `expect` turns that into a panic.
Solutions
- Place all entries under a common root directory/drive
- On Windows, avoid mixing drives (C:, D:) across entry paths
- Ensure user-defined entries are registered before the build when using the programmatic API
- Mark the module external with an absolute-path strategy that skips renormalization
Example fix
// before
entry: { main: 'C:/repo/main.ts', vendor: 'D:/shared/vendor.ts' }
// after
entry: { main: 'C:/repo/main.ts', vendor: 'C:/repo/vendor.ts' } Defensive patterns
Strategy: validation
Validate before calling
function assertCommonRoot(entries) {
const drives = new Set(entries.map(e => e.replace(/^[A-Za-z]:/, '').split(/[\\/]/)[0]));
const roots = new Set(entries.map(e => e.split(/[\\/]/)[0]));
if (roots.size > 1) throw new Error(`Entries share no common dir: ${[...roots].join(', ')}`);
}
// call before building: assertCommonRoot(Object.values(config.input)) Prevention
- Keep all entry files under one project root (and one drive on Windows)
- Use relative entry paths resolved from the project root
- Register entries before resolving externals when using the programmatic API
When it happens
Trigger: Declaring entries whose absolute paths share no common prefix (different drives on Windows, e.g. `C:\src` and `D:\lib`), or having no user-defined entries while an external module still requires renormalization.
Common situations: Windows monorepos spread across drives; programmatic API usage with entries on mixed mount points; constructing a bundler programmatically without registering entries before resolving externals.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Invalid file URL: must be absolute
- Invalid file URL: must not contain hostname
- Invalid file URL path: must not include encoded \ or /…
- The glob " " matches a tsconfig `paths` entry with multiple…
AI-assisted analysis of rolldown/rolldown@91b44b9d7b (2026-09-07).
Data as JSON: /api/errors/ca8c6cbf680a4441.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rolldown/src/module_loader/external_module_task.rs:77
id,
is_entry: false,
importers: FxIndexSet::default(),
dynamic_importers: FxIndexSet::default(),
imported_ids: FxIndexSet::default(),
dynamically_imported_ids: FxIndexSet::default(),
exports: vec![],
input_format: ExportsKind::None,
}),
);
let need_renormalize_render_path =
!matches!(resolved_id.external, ResolvedExternal::Absolute) && resolved_id.id.is_path();
let file_name: ArcStr = if need_renormalize_render_path {
let entries_common_dir = commondir::common_dir(
self.user_defined_entries.iter().map(|(_, resolved_id)| resolved_id.id.as_str()),
)
.expect("should have common dir for entries");
let relative_path = Path::new(resolved_id.id.as_str()).relative(&entries_common_dir);
ArcStr::from(relative_path.to_slash())
} else {
resolved_id.id.as_arc_str().clone()
};
let identifier_name: ArcStr = if need_renormalize_render_path {
let relative_path = Path::new(resolved_id.id.as_str()).relative(&self.ctx.options.cwd);
ArcStr::from(relative_path.to_slash())
} else {
resolved_id.id.as_arc_str().clone()
};
let legitimized_identifier_name = legitimize_identifier_name(&identifier_name);
let msg = ModuleLoaderMsg::ExternalModuleDone(Box::new(ExternalModuleTaskResult {
idx: self.module_idx,
id: resolved_id.id.clone(),
name: file_name,
identifier_name: legitimized_identifier_name.into(),View on GitHub (pinned to 91b44b9d7b)