nodejs/node · error · GypError

Duplicate target name "%s" in directory "%s" used both in "%

Error message

Duplicate target name "%s" in directory "%s" used both in "%s" and "%s".

What it means

While resolving a list of target specifiers, gyp builds a 'used' map keyed by 'subdir:target_name'. When the same key appears twice it means two included .gyp files in the same directory expose a target with the same name, which would create ambiguity in qualified references. The message names the directory, the new file, and the previously-seen file.

Source

Thrown at tools/gyp/pylib/gyp/input.py:2909

      targets: A list of targets in the form 'path/to/file.gyp:target_name'.
    """
    # Keep a dict going from 'subdirectory:target_name' to 'foo.gyp'.
    used = {}
    for target in targets:
        # Separate out 'path/to/file.gyp, 'target_name' from
        # 'path/to/file.gyp:target_name'.
        path, name = target.rsplit(":", 1)
        # Separate out 'path/to', 'file.gyp' from 'path/to/file.gyp'.
        subdir, gyp = os.path.split(path)
        # Use '.' for the current directory '', so that the error messages make
        # more sense.
        if not subdir:
            subdir = "."
        # Prepare a key like 'path/to:target_name'.
        key = subdir + ":" + name
        if key in used:
            # Complain if this target is already used.
            raise GypError(
                'Duplicate target name "%s" in directory "%s" used both '
                'in "%s" and "%s".' % (name, subdir, gyp, used[key])
            )
        used[key] = gyp


def SetGeneratorGlobals(generator_input_info):
    # Set up path_sections and non_configuration_keys with the default data plus
    # the generator-specific data.
    global path_sections
    path_sections = set(base_path_sections)
    path_sections.update(generator_input_info["path_sections"])

    global non_configuration_keys
    non_configuration_keys = base_non_configuration_keys[:]
    non_configuration_keys.extend(generator_input_info["non_configuration_keys"])

    global multiple_toolsets

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Rename one of the colliding targets so it is unique within that directory.
  2. If the two targets are actually the same, delete the duplicate and keep a single definition.
  3. Re-run gyp.

Example fix

// in dir foo/: a.gyp defines target 'bar'; b.gyp also defines target 'bar'
// before
foo/b.gyp: { 'targets': [{ 'target_name': 'bar', ... }] }
// after
foo/b.gyp: { 'targets': [{ 'target_name': 'bar_extra', ... }] }
Defensive patterns

Strategy: validation

Validate before calling

# Detect same-directory target-name collisions across included gyp files.
used = {}
for spec in target_specs:  # each like 'path/to/file.gyp:name'
    path, name = spec.rsplit(':', 1)
    subdir, gyp_file = os.path.split(path)
    subdir = subdir or '.'
    key = subdir + ':' + name
    if key in used:
        raise ValueError(f'duplicate target {name} in {subdir} ({used[key]} vs {gyp_file})')
    used[key] = gyp_file

Type guard

def no_duplicate_target_names_in_dir(target_specs) -> bool:
    used = set()
    for spec in target_specs:
        path, name = spec.rsplit(':', 1)
        subdir = os.path.split(path)[0] or '.'
        key = subdir + ':' + name
        if key in used:
            return False
        used.add(key)
    return True

Prevention

When it happens

Trigger: Two distinct .gyp files within the same directory each define a target whose unqualified name is identical, and both are pulled into the same build.

Common situations: Adding a new .gyp file with a target name that already exists in a sibling file; merging targets from separate files without renaming; generating gyp files programmatically with colliding names.

Related errors


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