{"record":{"id":"bae15ca1c9914f51","repo":"nodejs/node","slug":"duplicate-target-definitions-for-target-name","errorCode":null,"errorMessage":"Duplicate target definitions for {target_name}","messagePattern":"Duplicate target definitions for (.+?)","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":1458,"sourceCode":"\n    |data| is a dict mapping loaded build files by pathname relative to the\n    current directory.  Values in |data| are build file contents.  For each\n    |data| value with a \"targets\" key, the value of the \"targets\" key is taken\n    as a list containing target dicts.  Each target's fully-qualified name is\n    constructed from the pathname of the build file (|data| key) and its\n    \"target_name\" property.  These fully-qualified names are used as the keys\n    in the returned dict.  These keys provide access to the target dicts,\n    the dicts in the \"targets\" lists.\n    \"\"\"\n\n    targets = {}\n    for build_file in data[\"target_build_files\"]:\n        for target in data[build_file].get(\"targets\", []):\n            target_name = gyp.common.QualifiedTarget(\n                build_file, target[\"target_name\"], target[\"toolset\"]\n            )\n            if target_name in targets:\n                raise GypError(\"Duplicate target definitions for \" + target_name)\n            targets[target_name] = target\n\n    return targets\n\n\ndef QualifyDependencies(targets):\n    \"\"\"Make dependency links fully-qualified relative to the current directory.\n\n    |targets| is a dict mapping fully-qualified target names to their target\n    dicts.  For each target in this dict, keys known to contain dependency\n    links are examined, and any dependencies referenced will be rewritten\n    so that they are fully-qualified and relative to the current directory.\n    All rewritten dependencies are suitable for use as keys to |targets| or a\n    similar dict.\n    \"\"\"\n\n    all_dependency_sections = [\n        dep + op for dep in dependency_sections for op in (\"\", \"!\", \"/\")","sourceCodeStart":1440,"sourceCodeEnd":1476,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L1440-L1476","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — two files both have\n'target_name': 'util',\n// after — rename one\n'target_name': 'util_v2',","handlingStrategy":"validation","validationCode":"names = {}\nfor bf in data['target_build_files']:\n    for t in data[bf].get('targets', []):\n        qn = f\"{bf}:{t['target_name']}:{t['toolset']}\"\n        assert qn not in names, f'Duplicate target {qn} (also in {names[qn]})'\n        names[qn] = bf","typeGuard":"def targets_are_unique(data) -> bool:\n    seen = set()\n    for bf in data['target_build_files']:\n        for t in data[bf].get('targets', []):\n            qn = (bf, t['target_name'], t['toolset'])\n            if qn in seen:\n                return False\n            seen.add(qn)\n    return True","tryCatchPattern":null,"preventionTips":["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."],"tags":["gyp","targets","duplicate","build-config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}