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

  1. Rename one of the colliding target_name values so the qualified names differ.
  2. If the duplicate is unintended (e.g. a stale file pulled in by wildcard), exclude it from the build or delete it.
  3. Use distinct toolsets only if multiple_toolsets is enabled — otherwise the toolset is collapsed and does not disambiguate.
  4. 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

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


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/bae15ca1c9914f51. Report an issue: GitHub.