rolldown/rolldown · error

Entry length exceeds u32::MAX

Error message

Entry length exceeds u32::MAX

What it means

While matching modules to their entries in code splitting, rolldown casts the module table length to u32. If the build contains more than u32::MAX modules, the cast overflows and panics. The message text ('Entry length') is misleading — the value is actually modules.len().

Solutions

  1. Reduce the module count of the build (it exceeds u32::MAX, far beyond any practical bundle)
  2. If this is a legitimate workload, file an issue to widen the index type to u64/usize
  3. For tooling that generates modules programmatically, cap generated module count
Defensive patterns

Strategy: validation

Validate before calling

// You cannot realistically count modules pre-build; guard at the tooling level by
// refusing builds whose source tree contains an implausible module count
const { count } = await countSourceFiles(root);
if (count >= 0xffffffff) throw new Error('Module count exceeds u32 index range');

Try / catch

try {
  const bundle = await rolldown(options);
} catch (e) {
  if (String(e.message).includes('Entry length exceeds u32::MAX')) {
    // Split the build; the module count is beyond any supported scale
  }
}

Prevention

When it happens

Trigger: self.link_output.module_table.modules.len() > u32::MAX at code_splitting.rs:90. Requires a bundle with over ~4.29 billion modules — a scalability ceiling, not a configuration error.

Common situations: Only reachable via synthetic stress tests, fuzzing, or generated mega-builds; unreachable for real-world projects.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of rolldown/rolldown@91b44b9d7b (2026-09-07). Data as JSON: /api/errors/8e11913353732bc2. Report an issue: GitHub.

Appendix: source

Thrown at crates/rolldown/src/stages/generate_stage/code_splitting.rs:90

        bits: BitSet::new(entries_len),
        share_count: 0,
        tags_bit_set: ModuleTagBitSet::default(),
      }; self.link_output.module_table.modules.len()];
    let mut bits_to_chunk = FxHashMap::with_capacity(entries_len as usize);

    let input_base = ArcStr::from(
      self
        .get_common_dir_of_all_modules(self.link_output.module_table.modules.as_vec())
        .unwrap_or_default(),
    );
    if self.options.preserve_modules {
      let modules_len = self
        .link_output
        .module_table
        .modules
        .len()
        .try_into()
        .expect("Entry length exceeds u32::MAX");
      for (idx, module) in self.link_output.module_table.modules.iter_enumerated() {
        let Module::Normal(module) = module else {
          continue;
        };
        let matched_entry =
          self.link_output.entries.get(&module.idx).and_then(|entries| entries.first());
        if !self.link_output.metas[module.idx].is_included {
          continue;
        }

        let count = idx.raw();
        let mut bits = BitSet::new(modules_len);
        bits.set_bit(count);
        let mut chunk = Chunk::new(
          matched_entry.and_then(|item| item.name.clone()),
          matched_entry.and_then(|item| item.file_name.clone()),
          bits.clone(),
          vec![],

View on GitHub (pinned to 91b44b9d7b)