angular/angular-cli · error · Error
Project name must be a valid npm package name.
Error message
Project name must be a valid npm package name.
What it means
ProjectDefinitionCollection._validateName enforces npm package naming rules with the regex /^(?:@\w[\w.-]*\/)?\w[\w.-]*$/. Names must be a string, optionally scoped (@scope/), start with a word character, and contain only word characters, dots, and hyphens. Anything else throws this Error.
Source
Thrown at packages/angular_devkit/core/src/workspace/definitions.ts:203
}
}
super.set(definition.name, project);
return project;
}
override set(name: string, value: ProjectDefinition): this {
this._validateName(name);
super.set(name, value);
return this;
}
private _validateName(name: string): void {
if (typeof name !== 'string' || !/^(?:@\w[\w.-]*\/)?\w[\w.-]*$/.test(name)) {
throw new Error('Project name must be a valid npm package name.');
}
}
}
export class TargetDefinitionCollection extends DefinitionCollection<TargetDefinition> {
constructor(
initial?: Record<string, TargetDefinition>,
listener?: DefinitionCollectionListener<TargetDefinition>,
) {
super(initial, listener);
}
add(
definition: {
name: string;
} & TargetDefinition,
): TargetDefinition {
if (this.has(definition.name)) {View on GitHub (pinned to bb72145f9a)
Solutions
- Rename the project to a valid npm-style name: lowercase-ish word chars, dots or hyphens, optional @scope/ prefix.
- Sanitize derived names: replace invalid characters with '-' before calling add.
- Validate with the same regex before calling: /^(?:@\w[\w.-]*\/)?\w[\w.-]*$/.test(name).
Example fix
// before
workspace.addProject({ name: 'my app', root: 'apps/my-app' });
// after
workspace.addProject({ name: 'my-app', root: 'apps/my-app' }); Defensive patterns
Strategy: validation
Validate before calling
const NAME_RE = /^(?:@\w[\w.-]*\/)?\w[\w.-]*$/;
if (typeof name !== 'string' || !NAME_RE.test(name)) {
throw new Error(`Invalid project name: ${JSON.stringify(name)}`);
}
workspace.addProject({ name, root }); Type guard
function isValidProjectName(name: unknown): name is string {
return typeof name === 'string' && /^(?:@\w[\w.-]*\/)?\w[\w.-]*$/.test(name);
} Try / catch
try {
project = workspace.addProject({ name, root });
} catch (e) {
if (/valid npm package name/.test(e.message)) {
const safe = name.replace(/[^\w.-]/g, '-').replace(/^[^\w]/, 'a');
project = workspace.addProject({ name: safe, root });
} else throw e;
} Prevention
- Test candidate names against the npm-name regex before calling add
- Sanitize folder-derived names (replace spaces/special chars with '-')
- Never allow empty or whitespace-only names from prompts; require input
- Keep scopes lowercase word characters, e.g. @myorg/pkg
When it happens
Trigger: addProject({ name }) or project collection set() with a name like 'my app', '1app', 'app/', 'app_name' (underscore is allowed by \w actually — but e.g. 'app!' is not), an empty string, or a scoped name with uppercase/invalid scope like '@Foo/bar'.
Common situations: Deriving project names from folder paths containing spaces or special chars; empty names from CLI prompts left blank; names with underscores or non-ASCII characters; scope names with capitals.
Related errors
- Project name already exists.
- "${name}" must be a JSON value.
- Target name already exists.
- Target name must be a string.
- Unable to read workspace file.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/a482ba6340717db3.
Report an issue: GitHub.