nodejs/node · error · ValueError

Found multiple PBXVariantGroup children with name ${child_na

Error message

Found multiple PBXVariantGroup children with name ${child_name} and path ${child_path}

What it means

Raised by PBXGroup._AddChildToDicts when a PBXVariantGroup (used for localizations, e.g. .lproj variants) being added has the same (name, path) combination as an existing PBXVariantGroup child. Variant groups represent localized resources and must be uniquely identified within a group by their name and path.

Source

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

    def HashablesForChild(self):
        # To avoid a circular reference the hashables used to compute a child id do
        # not include the child names.
        return XCHierarchicalElement.Hashables(self)

    def _AddChildToDicts(self, child):
        # Sets up this PBXGroup object's dicts to reference the child properly.
        child_path = child.PathFromSourceTreeAndPath()
        if child_path:
            if child_path in self._children_by_path:
                raise ValueError("Found multiple children with path " + child_path)
            self._children_by_path[child_path] = child

        if isinstance(child, PBXVariantGroup):
            child_name = child._properties.get("name", None)
            key = (child_name, child_path)
            if key in self._variant_children_by_name_and_path:
                raise ValueError(
                    "Found multiple PBXVariantGroup children with "
                    + "name "
                    + str(child_name)
                    + " and path "
                    + str(child_path)
                )
            self._variant_children_by_name_and_path[key] = child

    def AppendChild(self, child):
        # Callers should use this instead of calling
        # AppendProperty('children', child) directly because this function
        # maintains the group's dicts.
        self.AppendProperty("children", child)
        self._AddChildToDicts(child)

    def GetChildByName(self, name):
        # This is not currently optimized with a dict as GetChildByPath is because
        # it has few callers.  Most callers probably want GetChildByPath.  This

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Find the duplicate PBXVariantGroup entry in the gyp target's resource lists and remove it.
  2. Ensure each localization variant group has a unique name within its parent group.
  3. Consolidate multiple .lproj references into a single variant group rather than adding separate groups.

Example fix

# before
'mac_bundle_resources': [
  'en.lproj/Localizable.strings',
  'fr.lproj/Localizable.strings',
]
# (if these produce duplicate variant group names) merge into one variant group
# after — ensure the gyp config declares one variant group for the base name
'mac_bundle_resources': [
  '<(PRODUCT_NAME)/Localizable.strings',
]
Defensive patterns

Strategy: validation

Validate before calling

# Ensure localization variant group names are unique within a group
seen = set()
for res in resources:
    name = os.path.splitext(os.path.basename(res))[0]
    if name in seen:
        raise ValueError(f'duplicate variant group name: {name}')
    seen.add(name)

Prevention

When it happens

Trigger: AppendChild is called with a PBXVariantGroup whose _properties['name'] and child_path match an existing entry in _variant_children_by_name_and_path. Two localization variant groups with the same name are added to the same parent group.

Common situations: Duplicate localized resource entries (e.g. two Localizable.strings variant groups) defined in the gyp config. A resources list that includes the same variant group twice. Misconfigured mac_bundle_resources or similar with overlapping localizations.

Related errors


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