evanw/esbuild · error · Error

Got null for source content for "${source}"

Error message

Got null for source content for "${source}"

What it means

Thrown at scripts/verify-source-map.js:845. After locating an identifier in the output, the harness calls map.sourceContentFor(source) to fetch the original source text from the source map's sourcesContent. A null return means the source map does not carry embedded source content for that source, so the reverse mapping cannot be checked.

Source

Thrown at scripts/verify-source-map.js:845

      outCodeMap = await fs.readFile(path.join(tempDir, `${outfile}.map`), 'utf8')
    }

    // Check the mapping of various key locations back to the original source
    const checkMap = (out, map) => {
      for (const id in toSearch) {
        const outIndex = out.indexOf(`"${id}"`)
        if (outIndex < 0) throw new Error(`Failed to find "${id}" in output`)
        const outLines = out.slice(0, outIndex).split('\n')
        const outLine = outLines.length
        const outLastLine = outLines[outLines.length - 1]
        let outColumn = outLastLine.length
        const { source, line, column } = map.originalPositionFor({ line: outLine, column: outColumn })

        const inSource = isStdin ? '<stdin>' : toSearch[id]
        recordCheck(decodeURI(source) === inSource, `expected source: ${inSource}, observed source: ${source}`)

        const inCode = map.sourceContentFor(source)
        if (inCode === null) throw new Error(`Got null for source content for "${source}"`)
        let inIndex = inCode.indexOf(`"${id}"`)
        if (inIndex < 0) inIndex = inCode.indexOf(`'${id}'`)
        if (inIndex < 0) throw new Error(`Failed to find "${id}" in input`)
        const inLines = inCode.slice(0, inIndex).split('\n')
        const inLine = inLines.length
        const inLastLine = inLines[inLines.length - 1]
        let inColumn = inLastLine.length

        const expected = JSON.stringify({ source, line: inLine, column: inColumn })
        const observed = JSON.stringify({ source, line, column })
        recordCheck(expected === observed, `expected original position: ${expected}, observed original position: ${observed}`)

        // Also check the reverse mapping
        const positions = map.allGeneratedPositionsFor({ source, line: inLine, column: inColumn })
        recordCheck(positions.length > 0, `expected generated positions: 1, observed generated positions: ${positions.length}`)
        let found = false
        for (const { line, column } of positions) {
          if (line === outLine && column === outColumn) {

View on GitHub (pinned to f6058f8364)

Solutions

  1. Ensure the esbuild invocation enables embedded source content (do not strip sourcesContent; avoid options that drop it).
  2. Check that the `source` path from originalPositionFor matches an entry in the map's `sources` array exactly (watch for URI-encoding/`../` differences).
  3. If content embedding is intentionally disabled, skip the sourceContentFor check in the test rather than expecting non-null.

Example fix

// before (build omits source content)
esbuild.build({ entryPoints, sourcemap: true, sourcesContent: false })

// after (embed source content so verification can read it)
esbuild.build({ entryPoints, sourcemap: true, sourcesContent: true })
Defensive patterns

Strategy: validation

Validate before calling

function hasSourceContentFor(map, source) {
  const c = map.sourceContentFor(source);
  return c !== null && c !== undefined;
}

Type guard

const hasSourceContent = (map, source) => map.sourceContentFor(source) != null;

Try / catch

try { const inCode = map.sourceContentFor(source); }
catch (e) {
  if (/Got null for source content/.test(e.message)) console.error('Source map lacks sourcesContent for', source);
  throw e;
}

Prevention

When it happens

Trigger: esbuild was run in a mode that omits sourcesContent (the generated .map has no `sourcesContent` array, or a null entry for that source). This happens when source maps are generated without embedding source text, when the source path normalization differs between `sources` and `sourcesContent`, or when an intermediate transform strips the content.

Common situations: A source-map config change disables content embedding, a bundling/chaining step drops sourcesContent, or the `source` string returned by originalPositionFor (after decodeURI) does not exactly match an entry in the sources list.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/9115bfef1b2b472f. Report an issue: GitHub.