nodejs/node · error · GypError

%s must not contain included_files key

Error message

%s must not contain included_files key

What it means

Raised as a GypError by LoadTargetBuildFile when a .gyp file already contains an 'included_files' key at the top level. gyp itself populates 'included_files' to track which .gypi files contributed to a target, so a user-supplied key of that name would collide and corrupt that bookkeeping.

Source

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

            # Already loaded.
            return False
        data["target_build_files"].add(build_file_path)

    gyp.DebugOutput(
        gyp.DEBUG_INCLUDES, "Loading Target Build File '%s'", build_file_path
    )

    build_file_data = LoadOneBuildFile(
        build_file_path, data, aux_data, includes, True, check
    )

    # Store DEPTH for later use in generators.
    build_file_data["_DEPTH"] = depth

    # Set up the included_files key indicating which .gyp files contributed to
    # this target dict.
    if "included_files" in build_file_data:
        raise GypError(build_file_path + " must not contain included_files key")

    included = GetIncludedBuildFiles(build_file_path, aux_data)
    build_file_data["included_files"] = []
    for included_file in included:
        # included_file is relative to the current directory, but it needs to
        # be made relative to build_file_path's directory.
        included_relative = gyp.common.RelativePath(
            included_file, os.path.dirname(build_file_path)
        )
        build_file_data["included_files"].append(included_relative)

    # Do a first round of toolsets expansion so that conditions can be defined
    # per toolset.
    ProcessToolsetsInDict(build_file_data)

    # Apply "pre"/"early" variable expansions and condition evaluations.
    ProcessVariablesAndConditionsInDict(
        build_file_data, PHASE_EARLY, variables, build_file_path

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Remove the 'included_files' key from the .gyp file; it is reserved for gyp's internal use.
  2. If you need to list include files, use the 'includes' key instead.
  3. Audit the file for any keys gyp manages internally (included_files) and remove them.

Example fix

// before (foo.gyp)
{
  'included_files': ['common.gypi'],
  'targets': [ ... ]
}
// after
{
  'includes': ['common.gypi'],
  'targets': [ ... ]
}
Defensive patterns

Strategy: validation

Validate before calling

RESERVED = {'included_files'}
for k in build_file_data:
    if k in RESERVED:
        raise ValueError(f'{k} is reserved; remove it from the .gyp file')

Type guard

def free_of_reserved_keys(data) -> bool:
    return 'included_files' not in data

Prevention

When it happens

Trigger: A target .gyp file includes an 'included_files' key in its top-level dict. gyp detects this at input.py:413 and refuses to overwrite it.

Common situations: Manually adding an 'included_files' key (mistaking it for a user-facing feature); copy-pasting gyp's internal output back into a source .gyp; a tool that round-trips gyp's processed dicts into source files.

Related errors


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