{"record":{"id":"c58a6d5ea32cdec3","repo":"nodejs/node","slug":"found-dependency-in-dependency-key-of-target","errorCode":null,"errorMessage":"Found {dependency} in {dependency_key} of {target}, but not in dependencies","messagePattern":"Found (.+?) in (.+?) of (.+?), but not in dependencies","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":1502,"sourceCode":"            for index, dep in enumerate(dependencies):\n                dep_file, dep_target, dep_toolset = gyp.common.ResolveTarget(\n                    target_build_file, dep, toolset\n                )\n                if not multiple_toolsets:\n                    # Ignore toolset specification in the dependency if it is specified.\n                    dep_toolset = toolset\n                dependency = gyp.common.QualifiedTarget(\n                    dep_file, dep_target, dep_toolset\n                )\n                dependencies[index] = dependency\n\n                # Make sure anything appearing in a list other than \"dependencies\" also\n                # appears in the \"dependencies\" list.\n                if (\n                    dependency_key != \"dependencies\"\n                    and dependency not in target_dict[\"dependencies\"]\n                ):\n                    raise GypError(\n                        \"Found \"\n                        + dependency\n                        + \" in \"\n                        + dependency_key\n                        + \" of \"\n                        + target\n                        + \", but not in dependencies\"\n                    )\n\n\ndef ExpandWildcardDependencies(targets, data):\n    \"\"\"Expands dependencies specified as build_file:*.\n\n    For each target in |targets|, examines sections containing links to other\n    targets.  If any such section contains a link of the form build_file:*, it\n    is taken as a wildcard link, and is expanded to list each target in\n    build_file.  The |data| dict provides access to build file dicts.\n","sourceCodeStart":1484,"sourceCodeEnd":1520,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L1484-L1520","documentation":"QualifyDependencies rewrites every dependency reference in sections derived from dependency_sections (dependencies, dependencies!, dependencies/) to its fully-qualified form. As a consistency rule, any dependency that appears in a non-primary section (dependencies! or dependencies/) must also appear in the plain 'dependencies' list of the same target. If it does not, GYP raises this GypError naming the dependency, the section it was found in, and the target. This enforces that hard deps and public-export deps are a subset of the build-time deps.","triggerScenarios":"A target lists a dep in 'dependencies!' (hard dependencies) or 'dependencies/' (dependents exported for include paths) but omits it from 'dependencies'; renaming a dep in one list but not the other; a refactor that moved a dep into dependencies! assuming it would be implicitly added to dependencies.","commonSituations":"Adding a header-only or link-time dep to 'dependencies!' and forgetting to mirror it in 'dependencies'; merging conditions that inject a dep into one list only; tooling that edits one section independently.","solutions":["Add the named dependency to the target's plain 'dependencies' list as well.","Re-audit dependencies! and dependencies/ to confirm each entry is also in dependencies.","If the dep was removed intentionally, remove it from all three sections consistently."],"exampleFix":"// before\n'dependencies': ['base'],\n'dependencies!': ['codegen'],   // codegen not in dependencies\n// after\n'dependencies': ['base', 'codegen'],\n'dependencies!': ['codegen'],","handlingStrategy":"validation","validationCode":"for section in ('dependencies!', 'dependencies/'):\n    for dep in target_dict.get(section, []):\n        assert dep in target_dict.get('dependencies', []), \\\n            f'{dep} listed in {section} of {target} but missing from dependencies'","typeGuard":"def aux_deps_are_subset_of_dependencies(target_dict) -> bool:\n    base = set(target_dict.get('dependencies', []))\n    return all(set(target_dict.get(s, [])) <= base\n               for s in ('dependencies!', 'dependencies/'))","tryCatchPattern":null,"preventionTips":["Whenever you add a dep to dependencies! or dependencies/, also add it to dependencies.","Keep the three dependency sections in sync during refactors.","Lint target dicts for the subset relationship before committing."],"tags":["gyp","dependencies","build-config","consistency"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}