swc-project/swc · error

Plan does not contain bundle kind for {:?}

Error message

Plan does not contain bundle kind for {:?}

What it means

After merging modules into bundles, swc_bundler looks each bundle's entry id up in the ChunkPlan (plan.entries) to recover its BundleKind. The plan and the merged-entry list are derived from the same module graph, so a missing id means the two data structures disagree — an internal chunk-planning invariant violation (this copy of the code is the non-inlining branch of the two).

Source

Thrown at crates/swc_bundler/src/bundler/chunk/mod.rs:110

            .collect::<Vec<_>>();

        let merged: Vec<_> = if entries.len() == 1 {
            entries
                .into_iter()
                .map(|(id, mut entry)| {
                    self.merge_into_entry(&ctx, id, &mut entry, &mut all);

                    #[cfg(debug_assertions)]
                    tracing::debug!("Merged `{}` and it's dep into an entry", id);

                    (id, entry)
                })
                .map(|(id, module)| {
                    let kind = plan
                        .entries
                        .get(&id)
                        .unwrap_or_else(|| {
                            unreachable!("Plan does not contain bundle kind for {:?}", id)
                        })
                        .clone();
                    Bundle {
                        kind,
                        id,
                        module: module.into(),
                    }
                })
                .collect()
        } else {
            entries
                .into_iter()
                .map(|(id, mut entry)| {
                    let mut a = all.clone();
                    self.merge_into_entry(&ctx, id, &mut entry, &mut a);

                    #[cfg(debug_assertions)]
                    tracing::debug!("Merged `{}` and it's dep into an entry", id);

View on GitHub (pinned to 5176682b65)

Solutions

  1. Update the whole swc workspace to a single version so chunk planning and merging run the same code
  2. If you implement Load/Resolve/ModuleRecord, guarantee one stable id per resolved module (return the same id for the same path every time)
  3. Simplify the entry list until the panic disappears to identify the conflicting entry, then report the reduced graph to swc
Defensive patterns

Strategy: fallback

Validate before calling

// Before bundling, assert every entry id is present in the module graph you feed in
fn entries_known(entries: &[ModuleId], graph: &FxHashSet<ModuleId>) -> Result<(), String> {
    for e in entries {
        if !graph.contains(e) {
            return Err(format!("entry {:?} missing from module graph", e));
        }
    }
    Ok(())
}

Try / catch

let modules = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    bundler.bundle(&entries)?
}));
if modules.is_err() {
    // fall back: bundle each entry separately (single-entry bundles avoid the merge/planning path)
    for e in &entries { let _ = bundler.bundle(std::iter::once(e).collect())?; }
}

Prevention

When it happens

Trigger: Running bundle generation where module ids differ between chunk planning and merging: custom loaders returning fresh ids per call (e.g. allocating a new Atom each load), virtual modules whose id is not stable across phases, or graphs where entry deduplication behaves differently in the plan vs the merge step.

Common situations: Custom ModuleRecord-building plugins or virtual-module loaders; bundling many entries that share dependencies; partial upgrades that leave swc_bundler and its sibling crates on mismatched versions.

Related errors


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