nodejs/node · error · ValueError

Multiple module definition files in one target, target %s li

Error message

Multiple module definition files in one target, target %s lists multiple .def files: %s

What it means

Raised as a ValueError by _GetModuleDefinition when a linkable target (shared_library, loadable_module, executable, windows_driver) lists more than one .def file among its sources. A module definition file controls linker exports; multiple .def files are ambiguous and MSVS/link cannot consume more than one, so gyp refuses to pick.

Source

Thrown at tools/gyp/pylib/gyp/generator/msvs.py:1402


def _GetDisabledWarnings(config):
    return [str(i) for i in config.get("msvs_disabled_warnings", [])]


def _GetModuleDefinition(spec):
    def_file = ""
    if spec["type"] in [
        "shared_library",
        "loadable_module",
        "executable",
        "windows_driver",
    ]:
        def_files = [s for s in spec.get("sources", []) if s.endswith(".def")]
        if len(def_files) == 1:
            def_file = _FixPath(def_files[0])
        elif def_files:
            raise ValueError(
                "Multiple module definition files in one target, target %s lists "
                "multiple .def files: %s" % (spec["target_name"], " ".join(def_files))
            )
    return def_file


def _ConvertToolsToExpectedForm(tools):
    """Convert tools to a form expected by Visual Studio.

    Arguments:
      tools: A dictionary of settings; the tool name is the key.
    Returns:
      A list of Tool objects.
    """
    tool_list = []
    for tool, settings in tools.items():
        # Collapse settings with lists.
        settings_fixed = {}

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Keep only one .def file in the target's sources; remove or exclude the others.
  2. Use conditions to select the correct .def per platform/configuration rather than listing all.
  3. If multiple exports are needed, merge them into a single .def file.

Example fix

// before
'sources': ['a.cc', 'exports_x86.def', 'exports_x64.def']
// after
'sources': ['a.cc'],
'conditions': [
  ['OS=="win" and target_arch=="x64"', { 'sources': ['exports_x64.def'] }],
  ['OS=="win" and target_arch=="ia32"', { 'sources': ['exports_x86.def'] }]
]
Defensive patterns

Strategy: validation

Validate before calling

def_files = [s for s in spec.get('sources', []) if s.endswith('.def')]
if len(def_files) > 1:
    raise ValueError(f"multiple .def files: {def_files}")

Type guard

def has_single_def(spec) -> bool:
    defs = [s for s in spec.get('sources', []) if s.endswith('.def')]
    return len(defs) <= 1

Prevention

When it happens

Trigger: A target of a linkable type whose 'sources' array contains two or more entries ending in '.def'. The list comprehension collecting def_files yields length > 1 at msvs.py:1397.

Common situations: Globbing sources with a pattern that catches multiple .def files; merging two libraries' sources into one target without dropping the redundant .def; platform-specific .def files for both architectures left in the same source list.

Related errors


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