{"record":{"id":"70dd45af3308628b","repo":"angular/angular-cli","slug":"emit-attempted-before-angular-webpack-plugin-initi","errorCode":null,"errorMessage":"Emit attempted before Angular Webpack plugin initialization.","messagePattern":"Emit attempted before Angular Webpack plugin initialization\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ngtools/webpack/src/ivy/symbol.ts","lineNumber":29,"sourceCode":"export interface EmitFileResult {\n  content?: string;\n  map?: string;\n  dependencies: readonly string[];\n  hash?: Uint8Array;\n}\n\nexport type FileEmitter = (file: string) => Promise<EmitFileResult | undefined>;\n\nexport class FileEmitterRegistration {\n  #fileEmitter?: FileEmitter;\n\n  update(emitter: FileEmitter): void {\n    this.#fileEmitter = emitter;\n  }\n\n  emit(file: string): Promise<EmitFileResult | undefined> {\n    if (!this.#fileEmitter) {\n      throw new Error('Emit attempted before Angular Webpack plugin initialization.');\n    }\n\n    return this.#fileEmitter(file);\n  }\n}\n\nexport class FileEmitterCollection {\n  #registrations: FileEmitterRegistration[] = [];\n\n  register(): FileEmitterRegistration {\n    const registration = new FileEmitterRegistration();\n    this.#registrations.push(registration);\n\n    return registration;\n  }\n\n  async emit(file: string): Promise<EmitFileResult | undefined> {\n    if (this.#registrations.length === 1) {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/ngtools/webpack/src/ivy/symbol.ts#L11-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before: prerender plugin added before Angular plugin manipulates emitter too early\nplugins: [new MyPrerenderPlugin(), new AngularWebpackPlugin()]\n\n// after: Angular plugin first, child-compilation plugins after\nplugins: [new AngularWebpackPlugin(), new MyPrerenderPlugin()]","handlingStrategy":"try-catch","validationCode":"// Verify the plugin is initialized before triggering child compilations or emitting\nif (!angularWebpackPlugin.isInitialized || typeof angularWebpackPlugin.fileEmitterUpdate !== 'function') {\n  throw new Error('AngularWebpackPlugin must be registered and initialized before child compilations emit');\n}\n// Ensure exactly one plugin instance per compiler\nconst count = compiler.options.plugins.filter(p => p instanceof AngularWebpackPlugin).length;\nif (count !== 1) throw new Error(`Expected 1 AngularWebpackPlugin, found ${count}`);","typeGuard":"function isInitialized(emitter) {\n  return typeof emitter === 'function';\n}","tryCatchPattern":"try {\n  const result = await fileEmitter.emit(file);\n} catch (err) {\n  if (err.message.includes('Emit attempted before Angular Webpack plugin initialization')) {\n    // wait for the main compilation to complete, then retry emit\n    await new Promise(res => compiler.hooks.afterCompile.tap('waitInit', res));\n    return fileEmitter.emit(file);\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["webpack","angular","plugin-lifecycle","child-compilation","initialization-order"],"backgroundTag":"plugin-initialization-order","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}