angular/angular-cli · warning
Project property "${name}" should be a string.
Error message
Project property "${name}" should be a string. What it means
While parsing a project definition in angular.json, the reader warns when the 'prefix', 'root', or 'sourceRoot' property is present but is not a string. The value is still copied through (cast), but behavior may be broken downstream.
Source
Thrown at packages/angular_devkit/core/src/workspace/json/reader.ts:209
for (const [name, value] of Object.entries<JsonValue>(projectNodeValue)) {
switch (name) {
case 'targets':
case 'architect': {
const nodes = findNodeAtLocation(projectNode, [name]);
if (!isJsonObject(value) || !nodes) {
context.error(`Invalid "${name}" field found; expected an object.`, value);
break;
}
hasTargets = true;
targets = parseTargetsObject(projectName, nodes, context);
jsonMetadata.hasLegacyTargetsName = name === 'architect';
break;
}
case 'prefix':
case 'root':
case 'sourceRoot':
if (typeof value !== 'string') {
context.warn(`Project property "${name}" should be a string.`, value);
}
if (properties) {
properties[name] = value as string;
}
break;
default:
if (!context.unprefixedProjectExtensions.has(name) && !/^[a-z]{1,3}-.*/.test(name)) {
context.warn(
`Project '${projectName}' contains extension with invalid name (${name}).`,
name,
);
}
if (extensions) {
extensions[name] = value;
}
break;
}
}View on GitHub (pinned to bb72145f9a)
Solutions
- Set the offending property to a proper string value (e.g. "root": "projects/my-app").
- Remove the property if it has no meaningful value (root defaults).
- Fix the generator/script that produced the non-string value.
Example fix
// before (angular.json)
"my-app": { "root": 0, "prefix": "app" }
// after
"my-app": { "root": "projects/my-app", "prefix": "app" } Defensive patterns
Strategy: type-guard
Validate before calling
const json = require('./angular.json');
for (const [name, p] of Object.entries(json.projects ?? {})) {
for (const key of ['prefix', 'root', 'sourceRoot']) {
if (key in p && typeof p[key] !== 'string') {
throw new Error(`projects.${name}.${key} must be a string, got ${typeof p[key]}: ${JSON.stringify(p[key])}`);
}
}
} Type guard
function isStringProp(v) {
return typeof v === 'string';
} Prevention
- Keep root/prefix/sourceRoot as strings; quote paths and prefix values.
- Ensure generators expand template placeholders before writing angular.json.
- Schema-validate angular.json in CI.
When it happens
Trigger: parseProject handles the 'prefix'/'root'/'sourceRoot' cases and finds typeof value !== 'string' (e.g. "root": 0 or "sourceRoot": true).
Common situations: Script-generated angular.json writing numbers/nulls; hand-edits quoting mistakes; template placeholders left unexpanded (e.g. "root": null).
Related errors
- Skipping invalid project value; expected an object.
- Skipping invalid target value; expected an object.
- Workspace extension with invalid name (${name}) found.
- Project '${projectName}' contains extension with invalid nam
- Invalid redirect status code: ${status}. Please use one of t
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/d47f4be5f651e5ae.
Report an issue: GitHub.