{"record":{"id":"f34ff825464110dc","repo":"angular/angular-cli","slug":"compilation-is-undefined","errorCode":null,"errorMessage":"compilation is undefined.","messagePattern":"compilation is undefined\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/build_angular/src/tools/webpack/plugins/index-html-webpack-plugin.ts","lineNumber":32,"sourceCode":"} from '@angular/build/private';\nimport { basename, dirname, extname } from 'node:path';\nimport { Compilation, Compiler, sources } from 'webpack';\nimport { assertIsError } from '../../../utils/error';\nimport { addError, addWarning } from '../../../utils/webpack-diagnostics';\n\nexport interface IndexHtmlWebpackPluginOptions\n  extends IndexHtmlGeneratorOptions,\n    Omit<IndexHtmlGeneratorProcessOptions, 'files'> {}\n\nconst PLUGIN_NAME = 'index-html-webpack-plugin';\nexport class IndexHtmlWebpackPlugin extends IndexHtmlGenerator {\n  private _compilation: Compilation | undefined;\n  get compilation(): Compilation {\n    if (this._compilation) {\n      return this._compilation;\n    }\n\n    throw new Error('compilation is undefined.');\n  }\n\n  constructor(override readonly options: IndexHtmlWebpackPluginOptions) {\n    super(options);\n  }\n\n  apply(compiler: Compiler) {\n    compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {\n      this._compilation = compilation;\n      compilation.hooks.processAssets.tapPromise(\n        {\n          name: PLUGIN_NAME,\n          stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE + 1,\n        },\n        callback,\n      );\n    });\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/build_angular/src/tools/webpack/plugins/index-html-webpack-plugin.ts#L14-L50","documentation":"IndexHtmlWebpackPlugin exposes a lazily-set `compilation` getter that returns the Compilation instance captured during hook execution. Because the plugin stores it privately (_compilation), reading `plugin.compilation` before webpack has applied the plugin throws this error. It signals the getter was accessed outside the plugin's normal apply/hook lifecycle.","triggerScenarios":"Accessing the `compilation` getter of an IndexHtmlWebpackPlugin instance before its `apply()` has run or outside a webpack compiler hook callback (e.g. directly after `new IndexHtmlWebpackPlugin(options)` in unit tests or custom code).","commonSituations":"Custom tests that instantiate the plugin and inspect `compilation` without running webpack; third-party tooling wrapping the plugin and reading its state too early; refactors that move logic out of the `process` hook into constructor-time code.","solutions":["Move any code that needs the Compilation into a webpack hook callback (e.g. thisCompilation / emit) where _compilation is guaranteed to be set","Guard the access: check the private _compilation (or wrap the getter call) and handle undefined instead of dereferencing the getter","In tests, run the plugin through a real webpack compilation (webpack(config).run) rather than instantiating it standalone"],"exampleFix":"// before\nconst html = plugin.compilation.assets['index.html'];\n// after\ncompilation.hooks.processAssets.tap({...}, () => {\n  const html = plugin.compilation.assets['index.html']; // safe: inside hook\n});","handlingStrategy":"type-guard","validationCode":"if (plugin['_compilation'] === undefined) {\n  throw new Error('access compilation only inside a webpack hook');\n}","typeGuard":"function hasCompilation(p: IndexHtmlWebpackPlugin): p is IndexHtmlWebpackPlugin & { compilation: Compilation } {\n  return (p as { _compilation?: Compilation })._compilation !== undefined;\n}","tryCatchPattern":"let compilation: Compilation | undefined;\ntry {\n  compilation = plugin.compilation;\n} catch {\n  compilation = undefined; // defer to hook callback\n}","preventionTips":["Only touch plugin.compilation inside compiler hooks","Drive the plugin through a real webpack build in tests","Never cache the getter result before apply() ran","Prefer using the hook-provided compilation argument instead of the getter"],"tags":["webpack","angular-cli","lifecycle","null-reference"],"backgroundTag":"compilation-not-initialized","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}