swc-project/swc · error

invalid source reference: {src_id}

Error message

invalid source reference: {src_id}

What it means

While decoding the `mappings` of a parsed input source map, swc_config tracks the source index as a delta: src_id = src_id + nums[1] per segment. After applying the delta, the absolute index must stay within the `sources` array bounds. If the accumulated src_id >= sources.len(), the mappings reference a source that does not exist, so decoding bails. This means the `sources` array and the `mappings` string are inconsistent with each other.

Source

Thrown at crates/swc_config/src/source_map.rs:83

                        }

                        nums.clear();
                        nums = parse_vlq_segment(segment)?;
                        dst_col = (i64::from(dst_col) + nums[0]) as u32;

                        let mut src = !0;
                        let mut name = !0;

                        if nums.len() > 1 {
                            if nums.len() != 4 && nums.len() != 5 {
                                bail!(
                                    "invalid vlq segment size; expected 4 or 5, got {}",
                                    nums.len()
                                );
                            }
                            src_id = (i64::from(src_id) + nums[1]) as u32;
                            if src_id >= sources.len() as u32 {
                                bail!("invalid source reference: {src_id}");
                            }

                            src = src_id;
                            src_line = (i64::from(src_line) + nums[2]) as u32;
                            src_col = (i64::from(src_col) + nums[3]) as u32;

                            if nums.len() > 4 {
                                name_id = (i64::from(name_id) + nums[4]) as u32;
                                if name_id >= names.len() as u32 {
                                    bail!("invalid name reference: {name_id}");
                                }
                                name = name_id;
                            }
                        }

                        tokens.push(RawToken {
                            dst_line: dst_line as u32,
                            dst_col,

View on GitHub (pinned to 5176682b65)

Solutions

  1. Regenerate the whole source map from the original producer so `sources` and `mappings` stay consistent
  2. If you must rewrite `sources`, keep the array length and order identical (rewrite entries in place instead of removing them)
  3. Validate mappings against sources length with a standard source-map library first and locate the offending segment
  4. Pass the source map as a JSON string (SourceMapContent::Json) or drop it if not strictly needed

Example fix

// before: sources rewritten and shrunk
map.sources = map.sources.map(shorten).filter(Boolean); // length changed!
config.input_source_map = Some(InputSourceMap::SourceMapFile(map.into()));

// after: rewrite in place, never change length/order
map.sources = map.sources
    .iter()
    .map(|s| shorten(s)) // returns a placeholder instead of removing
    .collect::<Vec<_>>();
Defensive patterns

Strategy: validation

Validate before calling

// Reject maps whose mappings can index outside `sources` before calling swc
const { decode } = require('vlq'); // or inline VLQ decoder
function indicesInRange(mappings, len) {
  let src = 0;
  for (const line of mappings.split(';'))
    for (const seg of line.split(',')) {
      if (!seg) continue;
      const f = seg.split(/(?=[A-Za-z0-9+/])/); // rough split; prefer vlq lib
      const nums = [...seg.matchAll(/[A-Za-z0-9+/]/g)];
      // decode properly with the vlq package in real code:
      // const parts = seg.match(/..../) etc.
      void f; void nums;
    }
  return true;
}
// In practice: const SourceMap = require('source-map'); new SourceMap.SourceMapConsumer(json) — throws on inconsistency.

Try / catch

try { await transform(src, { inputSourceMap: map }) } catch (e) { if (/invalid source reference/.test(e.message)) { map = null; return transform(src, {}); } throw e; }

Prevention

When it happens

Trigger: Passing an input source map object where `sources` was truncated/replaced (fewer entries) while `mappings` still carries deltas pointing past the end, or where mappings from a different file were spliced into this source map.

Common situations: Rewriting `sources` paths for deployment (e.g. stripping prefixes, deduplicating) while leaving mappings untouched; merging source maps from multiple chunks; a producer tool emitting 1-based or otherwise offset source indices; hand-rolled source map manipulation in build scripts.

Related errors


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