{"record":{"id":"ed59e489f947d8f1","repo":"angular/angular-cli","slug":"project-name-already-exists","errorCode":null,"errorMessage":"Project name already exists.","messagePattern":"Project name already exists\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/core/src/workspace/definitions.ts","lineNumber":150,"sourceCode":"\nexport class ProjectDefinitionCollection extends DefinitionCollection<ProjectDefinition> {\n  constructor(\n    initial?: Record<string, ProjectDefinition>,\n    listener?: DefinitionCollectionListener<ProjectDefinition>,\n  ) {\n    super(initial, listener);\n  }\n\n  add(definition: {\n    name: string;\n    root: string;\n    sourceRoot?: string;\n    prefix?: string;\n    targets?: Record<string, TargetDefinition | undefined>;\n    [key: string]: unknown;\n  }): ProjectDefinition {\n    if (this.has(definition.name)) {\n      throw new Error('Project name already exists.');\n    }\n    this._validateName(definition.name);\n\n    const project: ProjectDefinition = {\n      root: definition.root,\n      prefix: definition.prefix,\n      sourceRoot: definition.sourceRoot,\n      targets: new TargetDefinitionCollection(),\n      extensions: {},\n    };\n\n    if (definition.targets) {\n      for (const [name, target] of Object.entries(definition.targets)) {\n        if (target) {\n          project.targets.set(name, target);\n        }\n      }\n    }","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/core/src/workspace/definitions.ts#L132-L168","documentation":"WorkspaceDefinition.add() enforces unique project names. Before creating the ProjectDefinition it checks the underlying DefinitionCollection via has(name) and throws if a project with that name is already registered. Duplicate project names make angular.json targets/paths ambiguous, so the collection rejects them eagerly.","triggerScenarios":"Calling workspace.addProject({ name: 'my-app', root: '...' }) (or similar add) when a project named 'my-app' already exists in the WorkspaceDefinition.","commonSituations":"Generator/schematic run twice on the same workspace; programmatic script adding projects in a loop without deduplication; case is significant, but identical names from re-running code generation collide.","solutions":["Check workspace.has(name) before adding and reuse/update the existing project instead.","Generate a unique name (suffix the app name) when adding programmatically.","Use set() or remove the existing project first if replacement is intended."],"exampleFix":"// before\nconst project = workspace.addProject({ name: 'shared-ui', root: 'libs/shared-ui' });\n// after\nif (!workspace.has('shared-ui')) {\n  const project = workspace.addProject({ name: 'shared-ui', root: 'libs/shared-ui' });\n}","handlingStrategy":"validation","validationCode":"if (workspace.has(name)) {\n  throw new Error(`Project '${name}' already exists in workspace`);\n}\nconst project = workspace.addProject({ name, root });","typeGuard":"function canAddProject(ws: WorkspaceDefinition, name: string): boolean {\n  return typeof name === 'string' && !ws.has(name);\n}","tryCatchPattern":"try {\n  project = workspace.addProject({ name, root });\n} catch (e) {\n  if (e.message === 'Project name already exists.') {\n    project = workspace.getProject(name); // reuse existing\n  } else throw e;\n}","preventionTips":["Check workspace.has(name) before every addProject call","Make schematics idempotent: skip creation if the project already exists","Use set() when replacement semantics are intended"],"tags":["workspace","duplicate-name","angular-devkit"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}