swc-project/swc · error · anyhow::Error
Failed to resolve plugin path: {resolved_path:?}
Error message
Failed to resolve plugin path: {resolved_path:?} What it means
Thrown by swc's plugin loader (compile_wasm_plugins) when a plugin entry from jsc.experimental.plugins resolves successfully but the resolver returns a FileName variant other than FileName::Real. The plugin pipeline needs a real on-disk .wasm file to read bytes into the module cache (store_bytes_from_path), so a virtual, custom, or internal filename cannot be loaded. The error prints the whole resolved FileName for inspection.
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 d7d7434666)
Solutions
- Use a plain filesystem specifier for each plugin: a node_modules package name or a ./relative/path/pkg style path whose resolved target is a real .wasm on disk
- Verify the plugin package actually ships the wasm binary (ls node_modules/<plugin> and check the binary field / files) and reinstall it
- Print/inspect the {resolved_path:?} value in the error to see which FileName variant came back, then adjust the specifier so the resolver returns a real path
- If you inject a custom resolver/loader, ensure resolve() returns FileName::Real(PathBuf) for plugin specifiers
Example fix
// .swcrc before (non-path specifier)
"jsc": { "experimental": { "plugins": [ [ "https://cdn.example.com/my_plugin.wasm", {} ] ] } }
// .swcrc after (real, resolvable path)
"jsc": { "experimental": { "plugins": [ [ "my_swc_plugin", {} ] ] } }
// where node_modules/my_swc_plugin resolves to a real .wasm file Defensive patterns
Strategy: validation
Validate before calling
// Rust: before transform, confirm every plugin resolves to a real file
use std::path::PathBuf;
use swc_ecma_loader::resolvers::{NodeModulesResolver, Resolve};
fn plugins_resolvable(plugins: &[(&str, serde_json::Value)]) -> Result<(), String> {
let resolver = NodeModulesResolver::new(swc_ecma_loader::TargetEnv::Node, Default::default(), true);
for (name, _) in plugins {
let resolved = resolver
.resolve(&swc_common::FileName::Real(PathBuf::from(name)), name)
.map_err(|e| format!("plugin {name}: {e:#}"))?;
match resolved.filename {
swc_common::FileName::Real(p) => {
if !p.is_file() { return Err(format!("plugin {name}: not a file: {}", p.display())); }
}
other => return Err(format!("plugin {name}: resolved to non-real filename {other:?}")),
}
}
Ok(())
} Try / catch
// Wrap compile_wasm_plugins / transform setup and surface the plugin name
match result {
Ok(_) => {}
Err(err) if err.to_string().contains("Failed to resolve plugin path") => {
eprintln!("plugin config is invalid; check jsc.experimental.plugins entries: {err:#}");
std::process::exit(1);
}
Err(err) => return Err(err),
} Prevention
- Keep plugin entries as node_modules package names or plain relative paths - never URLs or virtual specifiers
- Verify the plugin package's files/binaries in CI (a small script asserting the .wasm exists)
- Run a smoke transform in CI so bad plugin specs fail the build, not production
When it happens
Trigger: A PluginConfig whose spec resolves through NodeModulesResolver to something non-Real, e.g. a URL or virtual module produced by a custom loader chain, or a FileName::Custom/FileName::Internal leaking out of the resolver. Concretely: calling swc core transform with jsc.experimental.plugins containing a specifier that is not a plain filesystem path (relative ./pkg or node_modules package name).
Common situations: Typo'd plugin names that hit a fallback resolver path, plugins specified as http URLs, using swc inside a bundler that swaps in virtual file names, or a plugin package that re-exports through a redirect the resolver represents as a custom filename.
Related errors
- Failed to serialize output: {e}
- Failed to unwrap Arc: other references to transform_result e
- Failed to convert pointer size to calculate: {msg}
- {msg}
- Unexpected error occurred while running plugin transform
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/c5bfb2567f5c4349.
Report an issue: GitHub.