nodejs/node · error · ValueError

Found multiple build files with path ${path}

Error message

Found multiple build files with path ${path}

What it means

Raised by a build phase's _AddPathToDict when a file path is added to a build phase (Sources, Resources, Frameworks, Copy Files) that already contains a PBXBuildFile for that exact path. Build phases track files by path to prevent the same file from appearing twice in the same phase, which would generate an invalid .pbxproj.

Source

Thrown at tools/gyp/pylib/gyp/xcodeproj_file.py:1885

        for pbxbuildfile in self._properties.get("files", []):
            self._AddBuildFileToDicts(pbxbuildfile)

    def FileGroup(self, path):
        # Subclasses must override this by returning a two-element tuple.  The
        # first item in the tuple should be the PBXGroup to which "path" should be
        # added, either as a child or deeper descendant.  The second item should
        # be a boolean indicating whether files should be added into hierarchical
        # groups or one single flat group.
        raise NotImplementedError(self.__class__.__name__ + " must implement FileGroup")

    def _AddPathToDict(self, pbxbuildfile, path):
        """Adds path to the dict tracking paths belonging to this build phase.

        If the path is already a member of this build phase, raises an exception.
        """

        if path in self._files_by_path:
            raise ValueError("Found multiple build files with path " + path)
        self._files_by_path[path] = pbxbuildfile

    def _AddBuildFileToDicts(self, pbxbuildfile, path=None):
        """Maintains the _files_by_path and _files_by_xcfilelikeelement dicts.

        If path is specified, then it is the path that is being added to the
        phase, and pbxbuildfile must contain either a PBXFileReference directly
        referencing that path, or it must contain a PBXVariantGroup that itself
        contains a PBXFileReference referencing the path.

        If path is not specified, either the PBXFileReference's path or the paths
        of all children of the PBXVariantGroup are taken as being added to the
        phase.

        If the path is already present in the phase, raises an exception.

        If the PBXFileReference or PBXVariantGroup referenced by pbxbuildfile
        are already present in the phase, referenced by a different PBXBuildFile

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Deduplicate the file path in the target's relevant list (sources, resources, frameworks, etc.).
  2. Audit any included .gypi files for files that also appear in the main .gyp.
  3. Check glob patterns for overlap and use more specific patterns or exclude lists.
  4. Re-run gyp after fixing to regenerate a clean .pbxproj.

Example fix

# before
'sources': ['src/a.c', 'src/b.c', 'src/a.c']
# after
'sources': ['src/a.c', 'src/b.c']
Defensive patterns

Strategy: validation

Validate before calling

# Deduplicate file paths per build phase before generation
phase_files = list(dict.fromkeys(phase_files))  # remove dupes preserving order

Prevention

When it happens

Trigger: AppendBuildFile or _AddBuildFileToDicts is called with a path string that already exists in self._files_by_path. This means the same source/resource/framework path is listed twice in a single build phase via the gyp configuration.

Common situations: A 'sources', 'mac_bundle_resources', 'link_settings'/'libraries', or similar list contains the same file path twice. Overlapping glob patterns. A file included via both direct listing and an include (.gypi) file.

Related errors


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