angular/angular-cli · error · Error
${formatDiagnostics(configResult.errors)}
Error message
${formatDiagnostics(configResult.errors)} What it means
readTsconfig delegates parsing and validation of the TypeScript configuration file to @angular/compiler-cli's readConfiguration. If the compiler-cli reports configuration errors (parse errors, invalid options, missing extends targets), the formatted diagnostics are thrown as a single Error. This is the Angular build system's way of surfacing TypeScript config problems before compilation starts.
Source
Thrown at packages/angular_devkit/build_angular/src/utils/read-tsconfig.ts:29
/**
* Reads and parses a given TsConfig file.
*
* @param tsconfigPath - An absolute or relative path from 'workspaceRoot' of the tsconfig file.
* @param workspaceRoot - workspaceRoot root location when provided
* it will resolve 'tsconfigPath' from this path.
*/
export async function readTsconfig(
tsconfigPath: string,
workspaceRoot?: string,
): Promise<ParsedConfiguration> {
const tsConfigFullPath = workspaceRoot ? path.resolve(workspaceRoot, tsconfigPath) : tsconfigPath;
const { formatDiagnostics, readConfiguration } = await import('@angular/compiler-cli');
const configResult = readConfiguration(tsConfigFullPath);
if (configResult.errors && configResult.errors.length) {
throw new Error(formatDiagnostics(configResult.errors));
}
return configResult;
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Read the diagnostics in the error message — they name the exact file and JSON path of each config error
- Fix the reported tsconfig errors (syntax, missing extends target, invalid compilerOptions)
- Confirm the tsConfig path in angular.json resolves to an existing file relative to the workspace root
- Align your TypeScript version with the one supported by your @angular-devkit/build_angular version
Example fix
// before
class App { }
// after
export class App { } Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'fs';
import * as JSONC from 'jsonc-parser';
const raw = readFileSync(tsconfigPath, 'utf8');
const errors: any[] = [];
JSONC.parse(raw, errors, { allowTrailingComma: true });
if (errors.length) throw new Error(`Invalid tsconfig ${tsconfigPath}: ${errors.map(e => e.error).join(', ')}`);
// also check extends target exists:
const cfg = JSONC.parse(raw);
if (cfg.extends && !require('fs').existsSync(require('path').resolve(require('path').dirname(tsconfigPath), cfg.extends))) {
throw new Error(`tsconfig extends target not found: ${cfg.extends}`);
} Type guard
function isTsConfigResult(r: unknown): r is { options: ts.CompilerOptions; fileNames: string[]; errors: ts.Diagnostic[] } {
return !!r && typeof r === 'object' && 'options' in r && 'fileNames' in r;
} Try / catch
let config;
try {
config = await readTsconfig(tsconfigPath);
} catch (e) {
// message contains formatted TS diagnostics; log and surface to user
console.error('tsconfig invalid:', (e as Error).message);
process.exit(1);
} Prevention
- Validate tsconfig files in CI with `tsc --noEmit -p tsconfig.json` before running Angular builds
- Use jsoncParser/schema validation when generating tsconfigs programmatically
- Keep TypeScript version aligned with the Angular CLI major version
- Don't hand-edit generated tsconfigs; fix the generator
When it happens
Trigger: Calling readTsconfig with a tsconfig path whose JSON is syntactically invalid (comments/trailing commas without JSON5 support, BOM issues), references an 'extends' file that doesn't exist, or contains compilerOptions values rejected by the TypeScript version bundled with the CLI.
Common situations: Typo in angular.json tsConfig path pointing at the wrong file, tsconfig.extends pointing at a deleted base config, incompatible compilerOptions after a TypeScript upgrade (e.g. removed 'target' values), hand-edited tsconfig with a stray comma.
Related errors
- No project name provided and no default project found in wor
- Unsupported package manager: "${name}"
- The configured package manager, '${this.descriptor.binary}',
- Memoize decorator can only be used on methods or get accesso
- Argument ${isNonPrimitive(arg) ? arg.toString() : arg} is JS
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/6f0ad59292e42dc6.
Report an issue: GitHub.