rolldown/rolldown · error
consumer-local route should have complete namespace targets
Error message
consumer-local route should have complete namespace targets
What it means
This is an internal invariant panic in rolldown's chunk-generation phase. When a namespace re-export is retained on a consumer-local re-export route, the bundler expects its order-state bookkeeping to already hold the complete list of namespace init targets for that route; `consumer_local_namespace_targets` returning None means that bookkeeping was never populated, i.e. the bundler's wrapped-ESM init ordering logic violated its own contract.
Solutions
- Reduce the input to a minimal reproduction (barrel file with circular `export *` + dynamic import) and file an issue at https://github.com/rolldown/rolldown/issues with the repro and rolldown version
- Try the latest rolldown version — this invariant is frequently fixed in patch releases
- Restructure the offending barrel files to use explicit named re-exports instead of `export *` to sidestep the consumer-local re-export route
- As a workaround, disable or adjust advanced chunking options (e.g. `experimental.strictExecutionOrder`, `advancedChunks`) that change wrapped-ESM init ordering
- Check whether a specific plugin is generating the re-export graph and bypass/replace it
Example fix
// before (problematic module graph)
// a.js: export * from './b.js'; export const a = 1;
// b.js: export * from './a.js';
// after
// a.js: export { b } from './b.js'; export const a = 1;
// b.js: export const b = 2; Defensive patterns
Strategy: validation
Validate before calling
// Pre-build sanity check for circular namespace re-exports
import { globSync } from 'node:fs';
// grep source for 'export *' chains; if a cycle exists, restructure before building
function hasExportStarCycle(files) {
const seen = new Set();
const visit = (f) => {
if (seen.has(f)) return true; seen.add(f);
return (readExportStars(f) || []).some(visit);
};
return files.some(visit);
}
if (hasExportStarCycle(entryFiles)) console.warn('circular export * detected: may trip rolldown wrapped-esm init invariant'); Type guard
function isRolldownPanic(err) {
return err instanceof Error && /consumer-local route should have complete namespace targets/.test(err.message);
} Try / catch
try {
await bundle();
} catch (err) {
if (/consumer-local route should have complete namespace targets/.test(String(err))) {
console.error('Rolldown internal invariant hit; report repro + version, or flatten export * chains');
process.exitCode = 1;
} else throw err;
} Prevention
- Prefer explicit named re-exports over `export *` in barrel files
- Avoid circular barrel-file graphs in monorepos
- Pin and regularly update rolldown versions; read changelogs for wrapped-ESM fixes
- Keep a minimal reproduction of the failing graph when reporting
- Test code-splitting-heavy graphs in CI so regressions surface early
When it happens
Trigger: Hitting this requires the chunk graph to contain a consumer-local namespace re-export (`export * from` / namespace re-export of a module that stays within the same chunk group) that is retained in the output while the wrapped-ESM init metadata pass finds no namespace targets recorded for that route. It is reached through normal `Bundle`/`rollup` builds, not a user-facing API call, and almost always indicates a bundler bug triggered by an unusual module graph shape (circular namespace re-exports mixed with dynamic imports or code-splitting).
Common situations: Large codebases with circular `export * from` chains combined with dynamic imports/entry-level code splitting; upgrading rolldown versions where the consumer-local re-export route detection changed; rare graph shapes in monorepos with barrel files that re-export each other.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Should have pre_rendered_chunk
- CJS entry should have a wrapper
- dynamic-entry module target should have a wrapper
- importee chunk should exist
- pre-chunk order CJS carrier should exist
AI-assisted analysis of rolldown/rolldown@91b44b9d7b (2026-09-07).
Data as JSON: /api/errors/65d52405d19fc8a1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rolldown/src/stages/generate_stage/compute_wrapped_esm_init_metadata.rs:284
namespace: namespace_reexport_is_retained,
},
) {
continue;
}
if stmt_is_included
&& overlay.is_none_or(|overlay| overlay.retained_reexport_path.is_empty())
{
continue;
}
} else if !is_reexport {
continue;
}
let mut targets = vec![];
if namespace_reexport_is_retained && ctx.order_state.is_consumer_local_reexport_route(root) {
let namespace_targets = ctx
.order_state
.consumer_local_namespace_targets(root)
.expect("consumer-local route should have complete namespace targets");
targets.extend(namespace_targets.iter().copied().filter(|target| match target {
WrappedEsmInitTarget::Module(module_idx) => {
ctx.order_state.esm_init_included_in_live_chunk(
&ctx.metas[*module_idx],
*module_idx,
ctx.chunk_graph,
)
}
WrappedEsmInitTarget::CjsCarrier(key) => {
ctx.order_state.order_cjs_carrier_included_in_live_chunk(*key, ctx.chunk_graph)
}
}));
} else if ctx.order_wrap {
// A recorded retained path restricts the hop walk to the chains resolved reads consumed.
// That is only sound when the path is the record's whole evidence: an included namespace
// (or forwarded dynamic exports) retains EVERY non-ambiguous export of this star record —
// including chains no resolved read recorded — so the walk must stay unrestricted there or
// the off-path pure definers lose their only init call site.View on GitHub (pinned to 91b44b9d7b)