swc-project/swc · error

Failed to resolve plugin path

Error message

Failed to resolve plugin path: {resolved_path:?}

What it means

While registering WASM plugins (the `jsc.experimental.plugins` list), swc resolved the plugin specifier through its resolver but the resulting FileName was not `FileName::Real` - e.g. External, Custom, or a virtual path - so there is no on-disk .wasm file to load into the plugin runtime cache (crates/swc/src/plugin.rs). A resolution failure produces the earlier wrapped context 'failed to resolve plugin path: {name}' instead.

Solutions

  1. Reference the plugin by a path that resolves to a real .wasm file (relative/absolute path or package with a real main)
  2. Verify the plugin package is installed and resolvable from the project (check node_modules layout; avoid PnP/virtual resolutions)
  3. If you implement the Resolve trait, return FileName::Real pointing at the actual .wasm on disk

Example fix

// before (.swcrc)
{ "jsc": { "experimental": { "plugins": [ ["@scope/transform", "{}"] ] } } }
// after (.swcrc)
{ "jsc": { "experimental": { "plugins": [ ["./plugins/transform.wasm", "{}"] ] } } }
Defensive patterns

Strategy: validation

Validate before calling

// JavaScript - confirm each plugin resolves to a real .wasm before compiling
import fs from 'node:fs';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
function assertPluginsOnDisk(plugins) {
  for (const [name] of plugins) {
    let resolved;
    try { resolved = require.resolve(name); } catch { resolved = name; }
    if (!fs.existsSync(resolved)) {
      throw new Error(`swc plugin does not resolve to a real file: ${name}`);
    }
  }
}

Prevention

When it happens

Trigger: A plugins entry whose resolved target is not a real file: bare package names resolving to external/URL targets, symlink- or PnP-style virtual paths, or a custom Resolve implementation returning a non-Real filename.

Common situations: plugins: ["@scope/my-plugin"] where the package is not installed as a real file (yarn PnP, pnpm virtual store edges); pointing at remote URLs; bundler integrations supplying their own resolver.

Related errors


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

Appendix: source

Thrown at crates/swc/src/plugin.rs:266

    let mut inner_cache = crate::config::PLUGIN_MODULE_CACHE
        .inner
        .get()
        .expect("Cache should be available")
        .lock();

    // Populate cache to the plugin modules if not loaded
    for plugin_config in plugins.iter() {
        let plugin_name = &plugin_config.0;

        if !inner_cache.contains(plugin_runtime, plugin_name) {
            let resolved_path = plugin_resolver
                .resolve(&FileName::Real(PathBuf::from(plugin_name)), plugin_name)
                .with_context(|| format!("failed to resolve plugin path: {plugin_name}"))?;

            let path = if let FileName::Real(value) = resolved_path.filename {
                value
            } else {
                anyhow::bail!("Failed to resolve plugin path: {resolved_path:?}");
            };

            inner_cache.store_bytes_from_path(plugin_runtime, &path, plugin_name)?;
            #[cfg(debug_assertions)]
            tracing::debug!("Initialized WASM plugin {plugin_name}");
        }
    }

    Ok(())
}

View on GitHub (pinned to 5176682b65)