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

  1. Place all entries under a common root directory/drive
  2. On Windows, avoid mixing drives (C:, D:) across entry paths
  3. Ensure user-defined entries are registered before the build when using the programmatic API
  4. 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

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


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)