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
- Change the export to reference a real identifier binding and re-bundle.
- 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.
- Patch the offending dependency or pre-transform sources before bundling.
- 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
- Screen modules inside your Load implementation — it is the single choke point every file passes through.
- Keep string-keyed APIs behind exported objects, not export specifiers.
- Alert on any dependency diff that introduces `export { "`.
- Add fixture tests bundling each dependency category (CJS, ESM, generated) to catch regressions early.
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
- module string names unimplemented
- module string names unimplemented
- module string names unimplemented
- module string names unimplemented
- module string names unimplemented
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/0501a98aa4ab4dbe.
Report an issue: GitHub.