angular/angular-cli · error · Error
Terser failed for unknown reason.
Error message
Terser failed for unknown reason.
What it means
optimizeWithTerser calls the Terser API (via the worker pool) and expects result.code to be a string. When Terser returns a non-string code — typically because minification failed and it returned an error object/undefined instead — this error is thrown as a fallback because Terser did not surface a specific message. It means the Terser minification step failed without a diagnosable reason.
Source
Thrown at packages/angular_devkit/build_angular/src/tools/webpack/plugins/javascript-optimizer-worker.ts:229
// esbuild in the first pass is used to minify function names
keep_fnames: true,
format: {
// ASCII output is enabled here as well to prevent terser from converting back to UTF-8
ascii_only: true,
wrap_func_args: false,
},
sourceMap:
sourcemaps &&
({
asObject: true,
// typings don't include asObject option
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any),
},
);
if (typeof result.code !== 'string') {
throw new Error('Terser failed for unknown reason.');
}
return { code: result.code, map: result.map as object };
}
/**
* Determines if an unknown value is an esbuild BuildFailure error object thrown by esbuild.
* @param value A potential esbuild BuildFailure error object.
* @returns `true` if the object is determined to be a BuildFailure object; otherwise, `false`.
*/
function isEsBuildFailure(value: unknown): value is BuildFailure {
return !!value && typeof value === 'object' && 'errors' in value && 'warnings' in value;
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Set optimization to false temporarily (angular.json: configurations.production.optimization=false) to confirm Terser is the failing step, then narrow down the offending chunk
- Check the bundle for syntax Terser cannot handle and transpile it earlier (adjust target/compilerOptions.target in tsconfig to a lower ES level)
- Pin/align the terser version with what @angular-devkit/build-angular expects (npm ls terser) and reinstall to fix hoisting mismatches
- Upgrade @angular-devkit/build-angular / Angular CLI to the latest patch to pick up Terser fixes
Example fix
// before (tsconfig.json)
{"compilerOptions": {"target": "ESNext"}}
// after
{"compilerOptions": {"target": "ES2020"}} Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof input !== 'string' || input.length === 0) {
throw new Error('invalid input passed to terser optimizer');
} Type guard
function isTerserResult(r: unknown): r is { code: string; map?: object } {
return typeof r === 'object' && r !== null && typeof (r as any).code === 'string';
} Try / catch
try {
const out = await optimizeWithTerser(/* ... */);
} catch (err) {
if (err.message === 'Terser failed for unknown reason.') {
logger.warn(`terser failed for ${file}; keeping unminified output`);
return { code: originalCode, map: undefined };
}
throw err;
} Prevention
- Keep tsconfig target within what Terser supports
- Pin the terser version alongside build-angular
- Test minification in CI so regressions surface early
- Temporarily disable optimization to isolate failing chunks
When it happens
Trigger: Running the JavaScriptOptimizerWorker's optimizeWithTerser on a file whose Terser invocation returns { code: undefined } — e.g. invalid or exotic ES syntax Terser cannot parse, or a Terser internal error swallowed by the worker.
Common situations: Bundling code with syntax unsupported by the configured Terser/ECMA target; oversized or malformed generated bundles; incompatibility between the terser version resolved and the one expected by build-angular after dependency drift.
Related errors
- esbuild implementation missing
- compilation is undefined.
- No options were specified to "postcss-cli-resources".
- Multiple bundles have been named the same: '${duplicates.joi
- The "@angular-devkit/build-angular:browser" builder is depre
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/7704357dbcf22150.
Report an issue: GitHub.