{"record":{"id":"9115bfef1b2b472f","repo":"evanw/esbuild","slug":"got-null-for-source-content-for-source","errorCode":null,"errorMessage":"Got null for source content for \"${source}\"","messagePattern":"Got null for source content for \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/verify-source-map.js","lineNumber":845,"sourceCode":"      outCodeMap = await fs.readFile(path.join(tempDir, `${outfile}.map`), 'utf8')\n    }\n\n    // Check the mapping of various key locations back to the original source\n    const checkMap = (out, map) => {\n      for (const id in toSearch) {\n        const outIndex = out.indexOf(`\"${id}\"`)\n        if (outIndex < 0) throw new Error(`Failed to find \"${id}\" in output`)\n        const outLines = out.slice(0, outIndex).split('\\n')\n        const outLine = outLines.length\n        const outLastLine = outLines[outLines.length - 1]\n        let outColumn = outLastLine.length\n        const { source, line, column } = map.originalPositionFor({ line: outLine, column: outColumn })\n\n        const inSource = isStdin ? '<stdin>' : toSearch[id]\n        recordCheck(decodeURI(source) === inSource, `expected source: ${inSource}, observed source: ${source}`)\n\n        const inCode = map.sourceContentFor(source)\n        if (inCode === null) throw new Error(`Got null for source content for \"${source}\"`)\n        let inIndex = inCode.indexOf(`\"${id}\"`)\n        if (inIndex < 0) inIndex = inCode.indexOf(`'${id}'`)\n        if (inIndex < 0) throw new Error(`Failed to find \"${id}\" in input`)\n        const inLines = inCode.slice(0, inIndex).split('\\n')\n        const inLine = inLines.length\n        const inLastLine = inLines[inLines.length - 1]\n        let inColumn = inLastLine.length\n\n        const expected = JSON.stringify({ source, line: inLine, column: inColumn })\n        const observed = JSON.stringify({ source, line, column })\n        recordCheck(expected === observed, `expected original position: ${expected}, observed original position: ${observed}`)\n\n        // Also check the reverse mapping\n        const positions = map.allGeneratedPositionsFor({ source, line: inLine, column: inColumn })\n        recordCheck(positions.length > 0, `expected generated positions: 1, observed generated positions: ${positions.length}`)\n        let found = false\n        for (const { line, column } of positions) {\n          if (line === outLine && column === outColumn) {","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/scripts/verify-source-map.js#L827-L863","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the esbuild invocation enables embedded source content (do not strip sourcesContent; avoid options that drop it).","Check that the `source` path from originalPositionFor matches an entry in the map's `sources` array exactly (watch for URI-encoding/`../` differences).","If content embedding is intentionally disabled, skip the sourceContentFor check in the test rather than expecting non-null."],"exampleFix":"// before (build omits source content)\nesbuild.build({ entryPoints, sourcemap: true, sourcesContent: false })\n\n// after (embed source content so verification can read it)\nesbuild.build({ entryPoints, sourcemap: true, sourcesContent: true })","handlingStrategy":"validation","validationCode":"function hasSourceContentFor(map, source) {\n  const c = map.sourceContentFor(source);\n  return c !== null && c !== undefined;\n}","typeGuard":"const hasSourceContent = (map, source) => map.sourceContentFor(source) != null;","tryCatchPattern":"try { const inCode = map.sourceContentFor(source); }\ncatch (e) {\n  if (/Got null for source content/.test(e.message)) console.error('Source map lacks sourcesContent for', source);\n  throw e;\n}","preventionTips":["Build with sourcesContent embedded (avoid sourcesContent: false) when running verification.","Ensure the `source` path matches an entry in `sources` exactly (mind URI encoding and relative paths).","Skip the sourceContentFor check if content embedding is intentionally disabled."],"tags":["test-harness","source-map","sources-content","verification","validation"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}