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

  1. Rename the key to the namespaced form 'xxx-name' (1-3 lowercase letters then dash), e.g. 'nx-myPlugin'.
  2. Correct the spelling if it was meant to be a known extension key.
  3. 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

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


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