{"record":{"id":"38a612c2a7e8e411","repo":"nodejs/node","slug":"duplicate-target-name-s-in-directory-s-used","errorCode":null,"errorMessage":"Duplicate target name \"%s\" in directory \"%s\" used both in \"%s\" and \"%s\".","messagePattern":"Duplicate target name \"(.+?)\" in directory \"(.+?)\" used both in \"(.+?)\" and \"(.+?)\"\\.","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":2909,"sourceCode":"      targets: A list of targets in the form 'path/to/file.gyp:target_name'.\n    \"\"\"\n    # Keep a dict going from 'subdirectory:target_name' to 'foo.gyp'.\n    used = {}\n    for target in targets:\n        # Separate out 'path/to/file.gyp, 'target_name' from\n        # 'path/to/file.gyp:target_name'.\n        path, name = target.rsplit(\":\", 1)\n        # Separate out 'path/to', 'file.gyp' from 'path/to/file.gyp'.\n        subdir, gyp = os.path.split(path)\n        # Use '.' for the current directory '', so that the error messages make\n        # more sense.\n        if not subdir:\n            subdir = \".\"\n        # Prepare a key like 'path/to:target_name'.\n        key = subdir + \":\" + name\n        if key in used:\n            # Complain if this target is already used.\n            raise GypError(\n                'Duplicate target name \"%s\" in directory \"%s\" used both '\n                'in \"%s\" and \"%s\".' % (name, subdir, gyp, used[key])\n            )\n        used[key] = gyp\n\n\ndef SetGeneratorGlobals(generator_input_info):\n    # Set up path_sections and non_configuration_keys with the default data plus\n    # the generator-specific data.\n    global path_sections\n    path_sections = set(base_path_sections)\n    path_sections.update(generator_input_info[\"path_sections\"])\n\n    global non_configuration_keys\n    non_configuration_keys = base_non_configuration_keys[:]\n    non_configuration_keys.extend(generator_input_info[\"non_configuration_keys\"])\n\n    global multiple_toolsets","sourceCodeStart":2891,"sourceCodeEnd":2927,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L2891-L2927","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rename one of the colliding targets so it is unique within that directory.","If the two targets are actually the same, delete the duplicate and keep a single definition.","Re-run gyp."],"exampleFix":"// in dir foo/: a.gyp defines target 'bar'; b.gyp also defines target 'bar'\n// before\nfoo/b.gyp: { 'targets': [{ 'target_name': 'bar', ... }] }\n// after\nfoo/b.gyp: { 'targets': [{ 'target_name': 'bar_extra', ... }] }","handlingStrategy":"validation","validationCode":"# Detect same-directory target-name collisions across included gyp files.\nused = {}\nfor spec in target_specs:  # each like 'path/to/file.gyp:name'\n    path, name = spec.rsplit(':', 1)\n    subdir, gyp_file = os.path.split(path)\n    subdir = subdir or '.'\n    key = subdir + ':' + name\n    if key in used:\n        raise ValueError(f'duplicate target {name} in {subdir} ({used[key]} vs {gyp_file})')\n    used[key] = gyp_file","typeGuard":"def no_duplicate_target_names_in_dir(target_specs) -> bool:\n    used = set()\n    for spec in target_specs:\n        path, name = spec.rsplit(':', 1)\n        subdir = os.path.split(path)[0] or '.'\n        key = subdir + ':' + name\n        if key in used:\n            return False\n        used.add(key)\n    return True","tryCatchPattern":null,"preventionTips":["Adopt a project-wide target_name convention (e.g. prefix with the component).","When adding a new .gyp file, grep sibling files in the same dir for the intended name.","Codegen that emits gyp must guarantee per-directory uniqueness."],"tags":["gyp","targets","duplicate","naming"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}