nodejs/node · error · GypError
Duplicate target definitions for {target_name}
Error message
Duplicate target definitions for {target_name} What it means
BuildTargetsDict iterates every target in every build file listed in data['target_build_files'] and builds a map keyed by the fully-qualified name '<build_file>:<target_name>:<toolset>' produced by gyp.common.QualifiedTarget. If two targets anywhere in the loaded set produce the same qualified name, the second one triggers this GypError. The collision is across all build files, not just within one file.
Source
Thrown at tools/gyp/pylib/gyp/input.py:1458
|data| is a dict mapping loaded build files by pathname relative to the
current directory. Values in |data| are build file contents. For each
|data| value with a "targets" key, the value of the "targets" key is taken
as a list containing target dicts. Each target's fully-qualified name is
constructed from the pathname of the build file (|data| key) and its
"target_name" property. These fully-qualified names are used as the keys
in the returned dict. These keys provide access to the target dicts,
the dicts in the "targets" lists.
"""
targets = {}
for build_file in data["target_build_files"]:
for target in data[build_file].get("targets", []):
target_name = gyp.common.QualifiedTarget(
build_file, target["target_name"], target["toolset"]
)
if target_name in targets:
raise GypError("Duplicate target definitions for " + target_name)
targets[target_name] = target
return targets
def QualifyDependencies(targets):
"""Make dependency links fully-qualified relative to the current directory.
|targets| is a dict mapping fully-qualified target names to their target
dicts. For each target in this dict, keys known to contain dependency
links are examined, and any dependencies referenced will be rewritten
so that they are fully-qualified and relative to the current directory.
All rewritten dependencies are suitable for use as keys to |targets| or a
similar dict.
"""
all_dependency_sections = [
dep + op for dep in dependency_sections for op in ("", "!", "/")View on GitHub (pinned to 1b2de5e052)
Solutions
- Rename one of the colliding target_name values so the qualified names differ.
- If the duplicate is unintended (e.g. a stale file pulled in by wildcard), exclude it from the build or delete it.
- Use distinct toolsets only if multiple_toolsets is enabled — otherwise the toolset is collapsed and does not disambiguate.
- Grep the loaded build files for the target_name in the message to find all definitions.
Example fix
// before — two files both have 'target_name': 'util', // after — rename one 'target_name': 'util_v2',
Defensive patterns
Strategy: validation
Validate before calling
names = {}
for bf in data['target_build_files']:
for t in data[bf].get('targets', []):
qn = f"{bf}:{t['target_name']}:{t['toolset']}"
assert qn not in names, f'Duplicate target {qn} (also in {names[qn]})'
names[qn] = bf Type guard
def targets_are_unique(data) -> bool:
seen = set()
for bf in data['target_build_files']:
for t in data[bf].get('targets', []):
qn = (bf, t['target_name'], t['toolset'])
if qn in seen:
return False
seen.add(qn)
return True Prevention
- Search the whole tree for a target_name before introducing a new one.
- When copying a .gyp file as a template, rename target_name immediately.
- Be aware that with multiple_toolsets off, the toolset does not disambiguate names.
When it happens
Trigger: Two .gyp files each define a target with the same target_name and toolset (e.g. both define target_name 'foo' with the default toolset); a single file lists the same target_name twice; wildcard includes pull in a file whose target collides with a local one; a target moved between files without renaming leaving a duplicate.
Common situations: Copying a .gyp file to bootstrap a new target and forgetting to rename target_name; merging two projects that each define a 'base' or 'common' target; toolset mismatches that collapse to the same qualified name when multiple_toolsets is off.
Related errors
- Duplicate target name "%s" in directory "%s" used both in "%
- | cannot handle absolute paths, got "%s"
- Error importing pymod_do_mainmodule (%s): %s
- Unknown command string '%s' in '%s'.
- %s while executing command '%s' in %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/bae15ca1c9914f51.
Report an issue: GitHub.