angular/angular-cli · error · Error
Invalid workspace file - expected JSON object.
Error message
Invalid workspace file - expected JSON object.
What it means
After reading, the parser (parseTree with trailing-comma support) must produce an object-typed AST with children. If the file parses to a non-object (array, string, number) or fails to produce a usable tree, the reader throws this Error because the workspace file format requires a top-level JSON object.
Source
Thrown at packages/angular_devkit/core/src/workspace/json/reader.ts:53
export interface JsonWorkspaceOptions {
allowedProjectExtensions?: string[];
allowedWorkspaceExtensions?: string[];
}
export async function readJsonWorkspace(
path: string,
host: WorkspaceHost,
options: JsonWorkspaceOptions = {},
): Promise<WorkspaceDefinition> {
const raw = await host.readFile(path);
if (raw === undefined) {
throw new Error('Unable to read workspace file.');
}
const ast = parseTree(raw, undefined, { allowTrailingComma: true, disallowComments: false });
if (ast?.type !== 'object' || !ast.children) {
throw new Error('Invalid workspace file - expected JSON object.');
}
// Version check
const versionNode = findNodeAtLocation(ast, ['version']);
if (!versionNode) {
throw new Error('Unknown format - version specifier not found.');
}
const version = versionNode.value;
if (version !== 1) {
throw new Error(`Invalid format version detected - Expected:[ 1 ] Found: [ ${version} ]`);
}
const context: ParserContext = {
host,
metadata: new JsonWorkspaceMetadata(path, ast, raw),
trackChanges: true,
unprefixedWorkspaceExtensions: new Set([
...ANGULAR_WORKSPACE_EXTENSIONS,View on GitHub (pinned to bb72145f9a)
Solutions
- Ensure the file's top level is a JSON object: { "version": 1, "projects": { ... } }.
- Restore the file from version control or regenerate it (ng new / ng generate config).
- Validate the JSON with a parser/linter before handing it to readWorkspace.
- Check for merge-conflict markers or truncated content and fix the file.
Example fix
// angular.json before
["projects"]
// angular.json after
{
"version": 1,
"projects": {}
} Defensive patterns
Strategy: validation
Validate before calling
import { readFile } from 'fs/promises';
const raw = await readFile('angular.json', 'utf8');
const parsed = JSON.parse(raw);
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error('angular.json top level must be a JSON object');
} Type guard
function isJsonObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
const ws = await readWorkspace('angular.json', host);
} catch (e) {
if (e.message.includes('expected JSON object')) {
console.error('angular.json is malformed (top level is not an object). Restore from git or regenerate with `ng generate config`.');
} else throw e;
} Prevention
- Never hand-edit angular.json's top-level structure to a non-object
- Resolve merge conflicts fully — search for <<<<<<< markers before parsing
- Lint angular.json as JSON in CI to catch truncation/structure damage
- Keep the file under version control so it can be restored quickly
When it happens
Trigger: angular.json containing '[...]' or a bare value like '"text"' or '123' at the top level; a file that is valid JSON but not an object; content that parses to nothing usable.
Common situations: Hand-edited angular.json that replaced the object with an array; file overwritten by a tool dumping a config list; merge conflicts resolved to non-object content; BOM/encoding issues producing an unparseable tree.
Related errors
- Project name already exists.
- "${name}" must be a JSON value.
- Project name must be a valid npm package name.
- Target name already exists.
- Target name must be a string.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/7811092a4c72cb07.
Report an issue: GitHub.