swc-project/swc · error

Modules reexported with `export * as foo from './foo'` shoul

Error message

Modules reexported with `export * as foo from './foo'` should be marked as a wrapped esm

What it means

swc_bundler merges re-exports while building chunks. For `export * as foo from './foo'` it emits a named export whose value is the wrapped-ESM module object of './foo', looked up in metadata recorded during import analysis (the same map behind scope.mark_as_wrapping_required). If the target module was never marked as a wrapped ESM, the lookup returns None and this unreachable!() fires. It is an internal invariant of the bundler, not a user-facing error channel.

Source

Thrown at crates/swc_bundler/src/bundler/chunk/merge.rs:1233

                                                                    module_var.into(),
                                                                ),
                                                                exported: Some(ns.name.clone()),
                                                                is_type_only: false,
                                                            },
                                                        );
                                                        extra.push(
                                                            NamedExport {
                                                                span: ns.span,
                                                                specifiers: vec![specifier],
                                                                src: None,
                                                                with: None,
                                                                type_only: false,
                                                            }
                                                            .into(),
                                                        );
                                                    }
                                                    None => {
                                                        unreachable!(
                                                            "Modules reexported with `export * as \
                                                             foo from './foo'` should be marked \
                                                             as a wrapped esm"
                                                        )
                                                    }
                                                }

                                                // Remove `export * as foo from ''`
                                                continue;
                                            }
                                            ModuleExportName::Str(..) => {
                                                unimplemented!("module string names unimplemented")
                                            }
                                            #[cfg(swc_ast_unknown)]
                                            _ => panic!("unable to access unknown nodes"),
                                        }
                                    }
                                }

View on GitHub (pinned to 5176682b65)

Solutions

  1. Rewrite the offending re-export: replace `export * as foo from './foo'` with `import * as foo from './foo'; export { foo };` or explicit named re-exports (`export { a, b } from './foo'`) and rebuild
  2. If the re-exported module is also an entry, remove it from the entry list (or stop re-exporting it) so it can be marked as wrapped ESM
  3. If you implement Load/ModuleRecord, return stable, identical module ids for the same resolved path so analysis and merge agree
  4. Align all swc crates to one release (cargo update within the same swc version) and, if it still panics, minimize the module graph and report it to the swc repo

Example fix

// before
export * as utils from './utils';

// after
import * as utils from './utils';
export { utils };
Defensive patterns

Strategy: validation

Validate before calling

// Scan module sources before bundling for `export * as ns from ...`
fn uses_export_star_as(src: &str) -> bool {
    src.lines().any(|l| {
        let t = l.trim();
        t.starts_with("export") && t.contains("*") && t.contains(" as ") && t.contains("from")
    })
}

for (path, src) in &sources {
    if uses_export_star_as(src) {
        eprintln!("skipping/rewriting {} (export * as unsupported)", path);
    }
}

Try / catch

let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    bundler.bundle(&entries)?
}));
match result {
    Ok(v) => v,
    Err(payload) => {
        let msg = payload
            .downcast_ref::<String>()
            .cloned()
            .or_else(|| payload.downcast_ref::<&str>().map(|s| s.to_string()))
            .unwrap_or_default();
        if msg.contains("wrapped esm") {
            // rewrite `export * as` occurrences in inputs and retry once
        } else {
            std::panic::resume_unwind(payload);
        }
    }
}

Prevention

When it happens

Trigger: Calling swc_bundler's Bundler::bundle on a graph where a module contains `export * as ns from './dep'` and './dep' has no wrapped-esm context recorded — typically when './dep' is itself listed as an entry, participates in a dependency cycle that skips the marking step, or when a custom Load/Resolve implementation returns modules whose ids/contexts differ between analysis and merge.

Common situations: Barrel/index files that aggregate with `export * as utils from './utils'`; tooling that pins swc_ecma_* crates at versions different from swc_bundler; bundling packages that re-export CJS dependencies as namespaces; deno-style bundling entrypoints.

Related errors


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