angular/angular-cli · error · Error
compilation is undefined.
Error message
compilation is undefined.
What it means
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.
Source
Thrown at packages/angular_devkit/build_angular/src/tools/webpack/plugins/index-html-webpack-plugin.ts:32
} from '@angular/build/private';
import { basename, dirname, extname } from 'node:path';
import { Compilation, Compiler, sources } from 'webpack';
import { assertIsError } from '../../../utils/error';
import { addError, addWarning } from '../../../utils/webpack-diagnostics';
export interface IndexHtmlWebpackPluginOptions
extends IndexHtmlGeneratorOptions,
Omit<IndexHtmlGeneratorProcessOptions, 'files'> {}
const PLUGIN_NAME = 'index-html-webpack-plugin';
export class IndexHtmlWebpackPlugin extends IndexHtmlGenerator {
private _compilation: Compilation | undefined;
get compilation(): Compilation {
if (this._compilation) {
return this._compilation;
}
throw new Error('compilation is undefined.');
}
constructor(override readonly options: IndexHtmlWebpackPluginOptions) {
super(options);
}
apply(compiler: Compiler) {
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
this._compilation = compilation;
compilation.hooks.processAssets.tapPromise(
{
name: PLUGIN_NAME,
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE + 1,
},
callback,
);
});
View on GitHub (pinned to bb72145f9a)
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
Example fix
// before
const html = plugin.compilation.assets['index.html'];
// after
compilation.hooks.processAssets.tap({...}, () => {
const html = plugin.compilation.assets['index.html']; // safe: inside hook
}); Defensive patterns
Strategy: type-guard
Validate before calling
if (plugin['_compilation'] === undefined) {
throw new Error('access compilation only inside a webpack hook');
} Type guard
function hasCompilation(p: IndexHtmlWebpackPlugin): p is IndexHtmlWebpackPlugin & { compilation: Compilation } {
return (p as { _compilation?: Compilation })._compilation !== undefined;
} Try / catch
let compilation: Compilation | undefined;
try {
compilation = plugin.compilation;
} catch {
compilation = undefined; // defer to hook callback
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- esbuild implementation missing
- Terser failed for unknown reason.
- No options were specified to "postcss-cli-resources".
- Multiple bundles have been named the same: '${duplicates.joi
- Unknown task dependency [ID: ${id.id}].
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/f34ff825464110dc.
Report an issue: GitHub.