angular/angular-cli · error
Emit attempted before Angular Webpack plugin initialization.
Error message
Emit attempted before Angular Webpack plugin initialization.
What it means
The plugin's #fileEmitter slot holds the FileEmitter used to resolve emitted files for child compilations. emit() throws this error when it is called before update() has installed a file emitter — i.e. webpack asked for a file emit (e.g. during a child compilation like SSG/prerender or JIT lazy child builds) before the Angular plugin finished initialization of the program. It is an ordering/lifecycle violation, not a file-level problem.
Source
Thrown at packages/ngtools/webpack/src/ivy/symbol.ts:29
export interface EmitFileResult {
content?: string;
map?: string;
dependencies: readonly string[];
hash?: Uint8Array;
}
export type FileEmitter = (file: string) => Promise<EmitFileResult | undefined>;
export class FileEmitterRegistration {
#fileEmitter?: FileEmitter;
update(emitter: FileEmitter): void {
this.#fileEmitter = emitter;
}
emit(file: string): Promise<EmitFileResult | undefined> {
if (!this.#fileEmitter) {
throw new Error('Emit attempted before Angular Webpack plugin initialization.');
}
return this.#fileEmitter(file);
}
}
export class FileEmitterCollection {
#registrations: FileEmitterRegistration[] = [];
register(): FileEmitterRegistration {
const registration = new FileEmitterRegistration();
this.#registrations.push(registration);
return registration;
}
async emit(file: string): Promise<EmitFileResult | undefined> {
if (this.#registrations.length === 1) {View on GitHub (pinned to bb72145f9a)
Solutions
- Ensure only one Angular compiler plugin instance is applied per webpack compiler and that custom webpack code does not copy/re-hook its fileEmitter callbacks across compilers.
- Update @ngtools/webpack, @angular-devkit/build-angular, and @angular/* to matching versions — several emit-ordering races were fixed in newer releases.
- If using SSG/prerendering with a custom webpack config, let the Angular-provided plugin handle child compilations instead of creating your own before compilation completes.
- Reorder custom webpack plugins so anything triggering child compilations runs after the Angular plugin's initialization (it should be registered first in the plugins array).
Example fix
// before: prerender plugin added before Angular plugin manipulates emitter too early plugins: [new MyPrerenderPlugin(), new AngularWebpackPlugin()] // after: Angular plugin first, child-compilation plugins after plugins: [new AngularWebpackPlugin(), new MyPrerenderPlugin()]
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the plugin is initialized before triggering child compilations or emitting
if (!angularWebpackPlugin.isInitialized || typeof angularWebpackPlugin.fileEmitterUpdate !== 'function') {
throw new Error('AngularWebpackPlugin must be registered and initialized before child compilations emit');
}
// Ensure exactly one plugin instance per compiler
const count = compiler.options.plugins.filter(p => p instanceof AngularWebpackPlugin).length;
if (count !== 1) throw new Error(`Expected 1 AngularWebpackPlugin, found ${count}`); Type guard
function isInitialized(emitter) {
return typeof emitter === 'function';
} Try / catch
try {
const result = await fileEmitter.emit(file);
} catch (err) {
if (err.message.includes('Emit attempted before Angular Webpack plugin initialization')) {
// wait for the main compilation to complete, then retry emit
await new Promise(res => compiler.hooks.afterCompile.tap('waitInit', res));
return fileEmitter.emit(file);
}
throw err;
} Prevention
- Register AngularWebpackPlugin before any plugin that spawns child compilations (html-webpack-plugin, prerender/SSG plugins).
- Use only one AngularWebpackPlugin instance per webpack compiler.
- Keep @ngtools/webpack, @angular-devkit/build-angular, and @angular/* versions in lockstep.
- For custom SSG/prerender setups, wait for the parent compilation to finish before reading emitted assets.
When it happens
Trigger: A child compilation (html-webpack-plugin, PrerenderPlugin/SSG, translations child builds) triggers the file emitter hook during plugin.beforeCompile/compilation phases before the parent plugin's initialize/creatingProgram stage installs the emitter via update(). Commonly seen with Angular Universal/SSR builders or multiple plugin instantiations where the wrong instance is hooked.
Common situations: Custom webpack configs adding extra child compilations that run before the Angular plugin is ready; two AngularCompilerPlugin instances sharing one compiler where the uninitialized one receives emit calls; plugin ordering issues in angular.json/webpack customizations; SSG builders racing the main compilation.
Related errors
- Webpack stats build result is required.
- The "application" and "browser-esbuild" builders do not supp
- Only the "application" and "browser-esbuild" builders suppor
- Only the "application" and "browser-esbuild" builders suppor
- Webpack Dev Server configuration was not set.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/70dd45af3308628b.
Report an issue: GitHub.