{"record":{"id":"a482ba6340717db3","repo":"angular/angular-cli","slug":"project-name-must-be-a-valid-npm-package-name","errorCode":null,"errorMessage":"Project name must be a valid npm package name.","messagePattern":"Project name must be a valid npm package name\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/core/src/workspace/definitions.ts","lineNumber":203,"sourceCode":"      }\n    }\n\n    super.set(definition.name, project);\n\n    return project;\n  }\n\n  override set(name: string, value: ProjectDefinition): this {\n    this._validateName(name);\n\n    super.set(name, value);\n\n    return this;\n  }\n\n  private _validateName(name: string): void {\n    if (typeof name !== 'string' || !/^(?:@\\w[\\w.-]*\\/)?\\w[\\w.-]*$/.test(name)) {\n      throw new Error('Project name must be a valid npm package name.');\n    }\n  }\n}\n\nexport class TargetDefinitionCollection extends DefinitionCollection<TargetDefinition> {\n  constructor(\n    initial?: Record<string, TargetDefinition>,\n    listener?: DefinitionCollectionListener<TargetDefinition>,\n  ) {\n    super(initial, listener);\n  }\n\n  add(\n    definition: {\n      name: string;\n    } & TargetDefinition,\n  ): TargetDefinition {\n    if (this.has(definition.name)) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/core/src/workspace/definitions.ts#L185-L221","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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)."],"exampleFix":"// before\nworkspace.addProject({ name: 'my app', root: 'apps/my-app' });\n// after\nworkspace.addProject({ name: 'my-app', root: 'apps/my-app' });","handlingStrategy":"validation","validationCode":"const NAME_RE = /^(?:@\\w[\\w.-]*\\/)?\\w[\\w.-]*$/;\nif (typeof name !== 'string' || !NAME_RE.test(name)) {\n  throw new Error(`Invalid project name: ${JSON.stringify(name)}`);\n}\nworkspace.addProject({ name, root });","typeGuard":"function isValidProjectName(name: unknown): name is string {\n  return typeof name === 'string' && /^(?:@\\w[\\w.-]*\\/)?\\w[\\w.-]*$/.test(name);\n}","tryCatchPattern":"try {\n  project = workspace.addProject({ name, root });\n} catch (e) {\n  if (/valid npm package name/.test(e.message)) {\n    const safe = name.replace(/[^\\w.-]/g, '-').replace(/^[^\\w]/, 'a');\n    project = workspace.addProject({ name: safe, root });\n  } else throw e;\n}","preventionTips":["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"],"tags":["workspace","naming-validation","npm-package-name","angular-devkit"],"backgroundTag":"invalid-package-name","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}