{"record":{"id":"b0dceeeaa11de852","repo":"swc-project/swc","slug":"codegen-of-export-default-from-foo","errorCode":null,"errorMessage":"codegen of `export default from 'foo';`","messagePattern":"codegen of `export default from 'foo';`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_codegen/src/module_decls.rs","lineNumber":263,"sourceCode":"            space!(emitter);\n            keyword!(emitter, \"as\");\n            space!(emitter);\n        }\n\n        emit!(self.local);\n\n        srcmap!(emitter, self, false);\n\n        Ok(())\n    }\n}\n\n#[node_impl]\nimpl MacroNode for ExportSpecifier {\n    fn emit(&mut self, emitter: &mut Macro) -> Result {\n        match self {\n            ExportSpecifier::Default(..) => {\n                unimplemented!(\"codegen of `export default from 'foo';`\")\n            }\n            ExportSpecifier::Namespace(ref node) => emit!(node),\n            ExportSpecifier::Named(ref node) => emit!(node),\n            #[cfg(swc_ast_unknown)]\n            _ => return Err(unknown_error()),\n        }\n\n        Ok(())\n    }\n}\n\n#[node_impl]\nimpl MacroNode for ExportNamespaceSpecifier {\n    fn emit(&mut self, emitter: &mut Macro) -> Result {\n        emitter.emit_leading_comments_of_span(self.span(), false)?;\n\n        srcmap!(emitter, self, true);\n","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/swc-project/swc/blob/d7d74346665e36e692aa07e13d4ee3ee692ee35c/crates/swc_ecma_codegen/src/module_decls.rs#L245-L281","documentation":"swc's parser accepts the ESNext 'export default from' proposal syntax (`export default from './m';`, `export v from './m';`) and represents it as `ExportSpecifier::Default`. The code generator has no printer for that node — it is expected to be desugared by the `export_default_from` pass (swc_ecma_transforms_proposal) before printing; emitting it directly hits `unimplemented!`.","triggerScenarios":"Parse a module with export-default-from syntax enabled, then run the codegen without applying the `export_default_from` transform in between — custom pass pipelines, AST round-trippers, plugins that print raw AST.","commonSituations":"Hand-built pass lists that enable the parser syntax flag but omit the matching transform; formatters/pretty-printers that parse and print without lowering; pass sets that regress after an swc upgrade.","solutions":["Add the `export_default_from` pass to the pass chain before codegen","Replace the proposal syntax with standard re-export syntax in the source","Disable export-default-from in the parser syntax config so the input is rejected early instead of panicking at print time"],"exampleFix":"// before\nexport default from './mod';\n\n// after (standard ES2015 re-export)\nexport { default as default } from './mod';","handlingStrategy":"validation","validationCode":"// Rust: before codegen, walk the module for ExportSpecifier::Default\nfn uses_export_default_from(m: &Module) -> bool {\n    m.body.iter().any(|item| matches!(item, ModuleItem::ModuleDecl(ModuleDecl::ExportNamedDecl(d))\n        if d.specifiers.iter().any(|s| matches!(s, ExportSpecifier::Default(..)))))\n}","typeGuard":"fn is_printable_export(s: &ExportSpecifier) -> bool {\n    !matches!(s, ExportSpecifier::Default(..))\n}","tryCatchPattern":"// Rust: isolate third-party printing of untrusted ASTs\nlet result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| emitter.emit_module(&module)));\nif result.is_err() { /* report and fall back to skipping re-print */ }","preventionTips":["Never enable a parser proposal flag without also adding its lowering pass to the chain","For parse-and-print tools, reject inputs containing `export default from` / `export v from` upfront"],"tags":["ecmascript","codegen","proposal","export"],"backgroundTag":null,"analyzedSha":"d7d74346665e36e692aa07e13d4ee3ee692ee35c","analyzedAt":"2026-08-16T12:41:13.160Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}