angular/angular-cli · warning
Project '${projectName}' contains extension with invalid nam
Error message
Project '${projectName}' contains extension with invalid name (${name}). What it means
While parsing a project in angular.json, any unrecognized key (a project extension) must either be a known unprefixed extension or match the 'aaa-*' (1-3 lowercase letters + dash) naming convention; otherwise the reader warns that the project contains an extension with an invalid name. The value is still retained as an extension.
Source
Thrown at packages/angular_devkit/core/src/workspace/json/reader.ts:217
}
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;
}
}
let collectionListener: DefinitionCollectionListener<TargetDefinition> | undefined;
if (context.trackChanges) {
collectionListener = (name, newValue, collection) => {
if (hasTargets) {
jsonMetadata.addChange(['projects', projectName, 'targets', name], newValue, 'target');
} else {
jsonMetadata.addChange(View on GitHub (pinned to bb72145f9a)
Solutions
- Rename the key to the namespaced form 'xxx-name' (1-3 lowercase letters then dash), e.g. 'nx-myPlugin'.
- Correct the spelling if it was meant to be a known extension key.
- Move the setting to the tool's own config file if it does not belong in angular.json.
Example fix
// before (angular.json project)
"my-app": { "root": "", "myPlugin": {} }
// after
"my-app": { "root": "", "x-myPlugin": {} } Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = new Set(['root', 'prefix', 'sourceRoot', 'projectType', 'architect', 'targets', 'generators', 'schematics', 'cli', 'implicitDependencies', 'tags']);
const json = require('./angular.json');
for (const [name, p] of Object.entries(json.projects ?? {})) {
for (const key of Object.keys(p)) {
if (!KNOWN.has(key) && !/^[a-z]{1,3}-.*/.test(key)) {
console.warn(`projects.${name}: invalid extension name '${key}' (use 'xxx-name' form)`);
}
}
} Type guard
function isValidProjectExtensionName(name) {
return /^[a-z]{1,3}-.*/.test(name);
} Prevention
- Namespace custom project keys as 'vendor-name' (1-3 lowercase letters + dash).
- Check third-party tool docs for their required angular.json key names before adding them.
- Avoid typos of standard keys (schematics/generators/targets) at project level.
When it happens
Trigger: parseProject's default branch sees a key not in root/prefix/sourceRoot/projectType/architect/targets/generator sets, fails /^[a-z]{1,3}-.*/, and is not in unprefixedProjectExtensions (e.g. "myPlugin": {...} inside a project).
Common situations: Third-party tools injecting project-level config under arbitrary keys; hand-added custom settings; typos of known extensions like 'schematics' or 'cli' at project level.
Related errors
- Workspace extension with invalid name (${name}) found.
- Skipping invalid project value; expected an object.
- Project property "${name}" should be a string.
- Skipping invalid target value; expected an object.
- Could not find the main bundle.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/17aace93148917a1.
Report an issue: GitHub.