angular/angular-cli · error · Error

The 'buildOptimizer' option cannot be used without 'aot'.

Error message

The 'buildOptimizer' option cannot be used without 'aot'.

What it means

generateWebpackConfig enforces that Build Optimizer (a TypeScript/Angular transform that only makes sense with ahead-of-time compilation) is never enabled when the AOT compilation flag is off. The check happens before any webpack configuration is generated, so the build fails fast at configuration time. It is a pure options-validation guard, not a runtime failure.

Source

Thrown at packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts:41

export type BrowserWebpackConfigOptions = WebpackConfigOptions<NormalizedBrowserBuilderSchema>;

export type WebpackPartialGenerator = (
  configurationOptions: BrowserWebpackConfigOptions,
) => (Promise<Configuration> | Configuration)[];

export async function generateWebpackConfig(
  workspaceRoot: string,
  projectRoot: string,
  sourceRoot: string | undefined,
  projectName: string,
  options: NormalizedBrowserBuilderSchema,
  webpackPartialGenerator: WebpackPartialGenerator,
  logger: BuilderContext['logger'],
  extraBuildOptions: Partial<NormalizedBrowserBuilderSchema>,
): Promise<Configuration> {
  // Ensure Build Optimizer is only used with AOT.
  if (options.buildOptimizer && !options.aot) {
    throw new Error(`The 'buildOptimizer' option cannot be used without 'aot'.`);
  }

  const tsConfigPath = path.resolve(workspaceRoot, options.tsConfig);
  const tsConfig = await readTsconfig(tsConfigPath);

  const buildOptions: NormalizedBrowserBuilderSchema = { ...options, ...extraBuildOptions };
  const wco: BrowserWebpackConfigOptions = {
    root: workspaceRoot,
    logger: logger.createChild('webpackConfigOptions'),
    projectRoot,
    sourceRoot,
    buildOptions,
    tsConfig,
    tsConfigPath,
    projectName,
  };

  wco.buildOptions.progress = defaultProgress(wco.buildOptions.progress);

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Enable AOT: add "aot": true next to "buildOptimizer": true in the configuration
  2. Remove the buildOptimizer option if you intentionally need a JIT build (Build Optimizer is meaningless in JIT)
  3. Split configurations: keep a production configuration with aot+buildOptimizer and a separate JIT configuration without it

Example fix

// angular.json before
"buildOptimizer": true
// after
"aot": true,
"buildOptimizer": true
Defensive patterns

Strategy: validation

Validate before calling

function assertBuildOptimizerNeedsAot(options: { aot?: boolean; buildOptimizer?: boolean }) {
  if (options.buildOptimizer && !options.aot) {
    throw new Error("The 'buildOptimizer' option cannot be used without 'aot'.");
  }
}
// run on your resolved angular.json options before scheduling the build

Type guard

function canUseBuildOptimizer(o: { aot?: boolean; buildOptimizer?: boolean }): o is { aot: true; buildOptimizer?: boolean } {
  return !o.buildOptimizer || o.aot === true;
}

Try / catch

try {
  await scheduleBuild(target, options);
} catch (e) {
  if ((e as Error).message.includes("cannot be used without 'aot'")) {
    // fix angular.json: set aot true or drop buildOptimizer
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting buildOptimizer: true in the builder options (angular.json target options, CLI --build-optimizer flag) while aot is false or omitted where the default is false.

Common situations: Mixing flags like `ng build --aot=false --build-optimizer`, inheriting target options in angular.json where one target sets buildOptimizer and another disables aot, copy-pasted configurations from JIT-mode setups.

Related errors


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