angular/angular-cli · error · Error
Target name already exists.
Error message
Target name already exists.
What it means
TargetDefinitionCollection.add() enforces unique target names within a project. If a target with the same name is already registered (checked via has(name)) it throws before validating/creating the target. Duplicate target names would make the 'project:target' selector ambiguous.
Source
Thrown at packages/angular_devkit/core/src/workspace/definitions.ts:222
}
}
}
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)) {
throw new Error('Target name already exists.');
}
this._validateName(definition.name);
const target = {
builder: definition.builder,
options: definition.options,
configurations: definition.configurations,
defaultConfiguration: definition.defaultConfiguration,
};
super.set(definition.name, target);
return target;
}
override set(name: string, value: TargetDefinition): this {
this._validateName(name);
View on GitHub (pinned to bb72145f9a)
Solutions
- Check project targets (has) before adding and skip or update the existing target.
- Use set() on the target collection if overwriting is intended.
- Remove the existing target first, then add the new one.
Example fix
// before
project.addTarget({ name: 'build', builder: '@angular-devkit/build-angular:browser' });
// after
if (!project.targets.has('build')) {
project.addTarget({ name: 'build', builder: '@angular-devkit/build-angular:browser' });
} Defensive patterns
Strategy: validation
Validate before calling
if (project.targets.has(targetName)) {
// skip or update instead of adding
} else {
project.addTarget({ name: targetName, builder, options });
} Type guard
function canAddTarget(project: ProjectDefinition, name: string): boolean {
return typeof name === 'string' && !project.targets.has(name);
} Try / catch
try {
project.addTarget({ name, builder });
} catch (e) {
if (e.message === 'Target name already exists.') {
project.targets.set(name, { builder, options }); // overwrite intentionally
} else throw e;
} Prevention
- Check targets.has(name) before addTarget, especially for standard names (build, serve, test)
- Make generators idempotent so re-running them does not re-add targets
- Use set() when you intend to replace an existing target configuration
When it happens
Trigger: Calling project.addTarget({ name: 'build', builder: '...' }) when a 'build' target already exists on that project.
Common situations: Schematic re-run adding standard targets (build, serve, test) twice; scripts that merge configurations from two sources; applying the same generator to a project twice.
Related errors
- Project name already exists.
- Target name must be a string.
- "${name}" must be a JSON value.
- Project name must be a valid npm package name.
- Unable to read workspace file.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/909337638faf663a.
Report an issue: GitHub.