swc-project/swc · error

Node path provider does not support using `{:?}` as a base f

Error message

Node path provider does not support using `{:?}` as a base file name

What it means

In the same NodePathProvider::try_resolve_import, the base (the importing file) must be FileName::Real (use its parent dir) or FileName::Anon (fall back to config base_dir / cwd). Any other FileName variant used as the base — Custom, Url, Internal — reaches the unreachable! because the provider cannot derive a directory to relativize from.

Source

Thrown at crates/swc_ecma_transforms_module/src/path.rs:330

            }
        };
        let mut base = match base {
            FileName::Real(v) => Cow::Borrowed(
                v.parent()
                    .ok_or_else(|| anyhow!("failed to get parent of {v:?}"))?,
            ),
            FileName::Anon => match &self.config.base_dir {
                Some(v) => Cow::Borrowed(&**v),
                None => {
                    if cfg!(target_arch = "wasm32") {
                        panic!("Please specify `filename`")
                    } else {
                        Cow::Owned(current_dir().expect("failed to get current directory"))
                    }
                }
            },
            _ => {
                unreachable!(
                    "Node path provider does not support using `{:?}` as a base file name",
                    base
                )
            }
        };

        if base.is_absolute() != target.is_absolute() {
            if base.is_absolute() {
                base = Cow::Owned(base.to_path_buf().clean());
            } else {
                base = Cow::Owned(absolute_base_path(self.config.base_dir.as_deref(), &base)?);
            }

            if target.is_absolute() {
                target = target.clean();
            } else {
                target = absolute_path(self.config.base_dir.as_deref(), &target)?;
            }

View on GitHub (pinned to 5176682b65)

Solutions

  1. Register virtual input files as FileName::Anon and set config.base_dir, or supply a real path via FileName::Real so a parent directory exists.
  2. For purely virtual pipelines, resolve imports yourself and disable specifier rewriting for those entries.
  3. Update swc_ecma_transforms_module in case newer builds accept Custom bases.
  4. Wrap the module transform in catch_unwind at your FFI boundary and fall back to unrewritten specifiers.

Example fix

// before: virtual file named with Custom breaks relativization
.cm.new_source_file(FileName::Custom("virtual/main.js".into()), src);

// after: use Anon + base_dir so the provider can resolve relatives
.cm.new_source_file(FileName::Anon, src);
// config.module_config.base_dir = Some(PathBuf::from("/project/virtual"));
Defensive patterns

Strategy: validation

Validate before calling

use swc_common::FileName;
fn usable_base(f: &FileName) -> bool { matches!(f, FileName::Real(_) | FileName::Anon) }
// before enabling jsc.transform.modules:
// assert!(usable_base(&input_filename), "base must be Real or Anon (set base_dir for Anon)");

Type guard

fn is_supported_base(f: &FileName) -> bool { matches!(f, FileName::Real(_) | FileName::Anon) }

Prevention

When it happens

Trigger: Enabling module transforms (jsc.transform.modules / import rewriting) on a compile whose input file was registered as FileName::Custom("...") or FileName::Url(..) instead of a real path or Anon — common in embedders that name virtual files with custom strings.

Common situations: Plugins compiling in-memory/virtual files but still expecting module resolution to work; wasm builds without a filename (the Anon arm additionally panics with `Please specify filename` unless base_dir/filename is set); tools copying swc configs between node and wasm environments.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/870bae42270345b8. Report an issue: GitHub.