angular/angular-cli · error

Failed to parse "${path}" as JSON. ${printParseErrorCode(err

Error message

Failed to parse "${path}" as JSON. ${printParseErrorCode(error)} at offset: ${offset}.

What it means

Thrown by HostTree.readJson when jsonc-parser reports a parse error while parsing the file's text content (trailing commas are allowed). The error includes the parser error code description and the character offset of the first error. It indicates the file content is not syntactically valid JSON/JSONC.

Source

Thrown at packages/angular_devkit/schematics/src/tree/host-tree.ts:330

      if (
        e instanceof TypeError ||
        (e as NodeJS.ErrnoException).code === 'ERR_ENCODING_INVALID_ENCODED_DATA'
      ) {
        throw new Error(`Failed to decode "${path}" as UTF-8 text.`, { cause: e });
      }
      throw e;
    }
  }

  readJson(path: string): JsonValue {
    const content = this.readText(path);
    const errors: ParseError[] = [];
    const result = jsoncParse(content, errors, { allowTrailingComma: true });

    // If there is a parse error throw with the error information
    if (errors[0]) {
      const { error, offset } = errors[0];
      throw new Error(
        `Failed to parse "${path}" as JSON. ${printParseErrorCode(error)} at offset: ${offset}.`,
      );
    }

    return result;
  }

  exists(path: string): boolean {
    return this._recordSync.isFile(this._normalizePath(path));
  }

  get(path: string): FileEntry | null {
    const p = this._normalizePath(path);
    if (this._recordSync.isDirectory(p)) {
      throw new PathIsDirectoryException(p);
    }
    if (!this._recordSync.exists(p)) {
      return null;

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Open the file and fix the JSON syntax at the reported offset (the message names the exact position).
  2. Validate the file with a JSON linter/parser (e.g. `node -e "JSON.parse(...)"` or a JSONC-aware validator) before running the schematic.
  3. If the file may legitimately be non-JSON, wrap readJson in try/catch and provide a default or fall back to readText/manual parsing.
  4. Strip a UTF-8 BOM before parsing if the file was saved with BOM.

Example fix

// before
const config = tree.readJson('/project/angular.json');
// after
let config;
try {
  config = tree.readJson('/project/angular.json');
} catch (e) {
  if (String(e).startsWith('Failed to parse')) {
    throw new Error('angular.json is invalid JSON — fix the syntax at the reported offset');
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const raw = tree.readText(path);
const errors: ParseError[] = [];
jsoncParse(raw, errors, { allowTrailingComma: true });
const isValidJson = errors.length === 0;

Type guard

function parsesAsJson(text: string): boolean {
  try { JSON.parse(text.replace(/^\uFEFF/, '')); return true; } catch { return false; }
}

Try / catch

try {
  const json = tree.readJson(path);
} catch (e) {
  if ((e as Error).message.startsWith('Failed to parse')) {
    // fall back to defaults or surface a friendly config error
  } else throw e;
}

Prevention

When it happens

Trigger: Calling tree.readJson(path) on a file containing malformed JSON: missing/extra commas or braces, unquoted or single-quoted keys, comments (unless JSONC-valid), truncated content, or a non-JSON file given a .json path.

Common situations: Hand-edited tsconfig/package/angular.json with a syntax mistake; a template-merged config producing invalid output; reading a .json file that is actually JSON5 or contains BOM issues.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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