swc-project/swc · error

swc-loader only accepts path. Got `{name}`

Error message

swc-loader only accepts path. Got `{name}`

What it means

In the swc_node_bundler's SwcLoader::load_file, the compiler's SourceMap is asked to load the file from disk, which requires an OS path. The function matches the incoming FileName and bails for any variant other than FileName::Real (Custom, Anon, Inline, etc.). The bundler's loader pipeline only supports inputs backed by a physical file path.

Source

Thrown at crates/swc_node_bundler/src/loaders/swc.rs:136

                    Default::default(),
                    None,
                    &mut Vec::new(),
                )
                .unwrap();
                return Ok(ModuleData {
                    fm,
                    module,
                    helpers: Default::default(),
                });
            }
        }

        let fm = self
            .compiler
            .cm
            .load_file(match name {
                FileName::Real(v) => v,
                _ => bail!("swc-loader only accepts path. Got `{name}`"),
            })
            .with_context(|| format!("failed to load file `{name}`"))?;

        if let FileName::Real(path) = name {
            if let Some(ext) = path.extension() {
                if ext == "json" {
                    let module = load_json_as_module(&fm)
                        .with_context(|| format!("failed to load json file at {}", fm.name))?;
                    return Ok(ModuleData {
                        fm,
                        module,
                        helpers: Default::default(),
                    });
                }
            }
        }

        #[cfg(debug_assertions)]

View on GitHub (pinned to 5176682b65)

Solutions

  1. Only hand FileName::Real(path) entries to the swc loader; write virtual content to a real temp/cache file first if needed
  2. Trace back the loader pipeline step that produced the non-Real FileName and keep the original path attached
  3. For in-memory modules, use a loader designed for them (e.g. json path above is still Real-based; the whole API is path-centric)

Example fix

// before
loader.load_file(FileName::Custom("virtual-entry.ts".into()))?; // bails

// after
let path = std::env::temp_dir().join("virtual-entry.ts");
std::fs::write(&path, source)?;
loader.load_file(FileName::Real(path))?;
Defensive patterns

Strategy: type-guard

Type guard

use swc_common::FileName;
fn asRealPath(f: &FileName) -> Option<&std::path::Path> {
    match f {
        FileName::Real(p) => Some(p),
        _ => None, // SwcLoader::load_file bails for Custom/Anon/etc.
    }
}

Try / catch

match loader.load_file(name.clone()) {
    Ok(data) => Ok(data),
    Err(e) if e.to_string().contains("swc-loader only accepts path") => {
        let p = materialize(&name)?; // write virtual content to disk
        loader.load_file(FileName::Real(p))
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Passing a FileName::Custom or FileName::Anon entry to the swc loader, e.g. when feeding virtually-generated or transformed modules into the bundler, or when a preceding pipeline step replaced the original Real filename with a synthetic identifier.

Common situations: Building custom bundling pipelines where modules come from memory (plugins, virtual entry points, playgrounds); integrating swc_node_bundler with loaders that tag files with custom names; after refactoring a loader chain the filename type silently changed.

Related errors


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