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

  1. 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.
  2. Update @ngtools/webpack, @angular-devkit/build-angular, and @angular/* to matching versions — several emit-ordering races were fixed in newer releases.
  3. 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.
  4. 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

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


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/70dd45af3308628b. Report an issue: GitHub.