swc-project/swc · error

module string names unimplemented

Error message

module string names unimplemented

What it means

During finalize, swc_bundler builds the runtime export object for a chunk and iterates named export specifiers. At finalize.rs:227 an export whose orig is a string (`export { "orig" as name }`, ModuleExportName::Str) reaches unimplemented!() because the generated KeyValueProp needs a real Ident binding, and a string name has none. The panic aborts bundling with exit code 101.

Source

Thrown at crates/swc_bundler/src/bundler/finalize.rs:227

                                    ExportSpecifier::Namespace(..) => {
                                        // unreachable
                                    }
                                    ExportSpecifier::Default(s) => {
                                        props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(
                                            KeyValueProp {
                                                key: PropName::Ident(IdentName::new(
                                                    atom!("default"),
                                                    DUMMY_SP,
                                                )),
                                                value: s.exported.into(),
                                            },
                                        ))));
                                    }
                                    ExportSpecifier::Named(s) => match s.exported {
                                        Some(ModuleExportName::Ident(exported)) => {
                                            let orig = match s.orig {
                                                ModuleExportName::Ident(ident) => ident,
                                                ModuleExportName::Str(..) => unimplemented!(
                                                    "module string names unimplemented"
                                                ),
                                                #[cfg(swc_ast_unknown)]
                                                _ => panic!("unable to access unknown nodes"),
                                            };
                                            props.push(PropOrSpread::Prop(Box::new(
                                                Prop::KeyValue(KeyValueProp {
                                                    key: PropName::Ident(exported.into()),
                                                    value: orig.into(),
                                                }),
                                            )));
                                        }
                                        Some(ModuleExportName::Str(..)) => {
                                            unimplemented!("module string names unimplemented")
                                        }
                                        #[cfg(swc_ast_unknown)]
                                        Some(_) => panic!("unable to access unknown nodes"),
                                        None => {

View on GitHub (pinned to d7d7434666)

Solutions

  1. Change the export to reference a real identifier binding and re-bundle.
  2. If the string name is required by consumers, expose it via a namespace object (`const ns = { "some name": value }; export { ns }`) instead of a string export specifier.
  3. Patch the offending dependency or pre-transform sources before bundling.
  4. Track swc_bundler's module-string-names support and remove the workaround after upgrading.

Example fix

// before
export { "some name" as someName };

// after
const someName = /* the actual binding */ 1;
export { someName };
Defensive patterns

Strategy: validation

Validate before calling

// Screen every module in the Loader before the bundler stores it
impl Load for MyLoader {
    fn load(&self, f: &FileName) -> Result<ModuleRecord, Error> {
        let rec = self.inner.load(f)?;
        let mut bad = StrExportScan::default();
        rec.module.visit_with(&mut bad);
        if !bad.locations.is_empty() {
            anyhow::bail!("{} uses string-named exports ({:?}); unsupported by swc_bundler", f, bad.locations);
        }
        Ok(rec)
    }
}

Type guard

fn exports_are_identifier_only(m: &swc_ecma_ast::Module) -> bool {
    use swc_ecma_visit::{Visit, VisitWith};
    struct Ok_(bool); impl Visit for Ok_ {
        fn visit_module_export_name(&mut self, n: &swc_ecma_ast::ModuleExportName) {
            if matches!(n, swc_ecma_ast::ModuleExportName::Str(_)) { self.0 = false; }
            n.visit_children_with(self);
        }
    }
    let mut v = Ok_(true); m.visit_with(&mut v); v.0
}

Try / catch

// finalize runs after most work; prefer load-time screening. If you must catch:
if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| bundler.bundle(part)?)) {
    if format!("{:?}", &p).contains("module string names") {
        log::error!("chunk finalize hit a string-named export; offending module list: {:?}", module_paths);
        return Err(anyhow::anyhow!("unsupported ES2022 string export name"));
    }
    std::panic::resume_unwind(p);
}

Prevention

When it happens

Trigger: The bundle graph contains `export { "some name" as alias }` (or the equivalent re-export from another module); finalize tries to emit `exports.alias = <binding>` and cannot resolve a binding for a string orig.

Common situations: Final-stage failures when bundling generated code (GraphQL codegen, i18n key modules) that uses string-named exports; a bundle that passes earlier passes and only dies at chunk finalization.

Related errors


AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16). Data as JSON: /api/errors/0501a98aa4ab4dbe. Report an issue: GitHub.