nodejs/node · error · ValueError

unrecognized enumerated value %s

Error message

unrecognized enumerated value %s

What it means

_Enumeration.ValidateMSBuild raises ValueError('unrecognized enumerated value %s') when an enumerated MSBuild setting receives a value not in its allowed _msbuild_values set. The set is built from the enumeration's label list (minus None placeholders) plus any 'new' values added at registration. ValidateMSBuild checks the final MSBuild-side vocabulary, so this fires when the gyp file supplies an MSBuild keyword the enumeration does not know.

Source

Thrown at tools/gyp/pylib/gyp/MSVSSettings.py:204

          In the rare cases where MSVS has skipped an index value, None is
          used in the array to indicate the unused spot.
      new: an array of labels that are new to MSBuild.
    """

    def __init__(self, label_list, new=None):
        _Type.__init__(self)
        self._label_list = label_list
        self._msbuild_values = {value for value in label_list if value is not None}
        if new is not None:
            self._msbuild_values.update(new)

    def ValidateMSVS(self, value):
        # Try to convert.  It will raise an exception if not valid.
        self.ConvertToMSBuild(value)

    def ValidateMSBuild(self, value):
        if value not in self._msbuild_values:
            raise ValueError("unrecognized enumerated value %s" % value)

    def ConvertToMSBuild(self, value):
        index = int(value)
        if index < 0 or index >= len(self._label_list):
            raise ValueError(
                "index value (%d) not in expected range [0, %d)"
                % (index, len(self._label_list))
            )
        label = self._label_list[index]
        if label is None:
            raise ValueError("converted value for %s not specified." % value)
        return label


# Instantiate the various generic types.
_boolean = _Boolean()
_integer = _Integer()
# For now, we don't do any special validation on these types:

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Look up the setting in MSVSSettings._msbuild_validators to see the accepted label set and use one of those exact strings.
  2. If migrating between VS versions, translate the old enumeration label to the equivalent in the target version.
  3. Use the integer-index form on the MSVS side (ValidateMSVS/ConvertToMSBuild) which maps indices to labels automatically.

Example fix

# before
'Optimization': 'Full',   # not in this enumeration's MSBuild labels

# after
'Optimization': 'MaxSpeed',  # accepted label
Defensive patterns

Strategy: validation

Validate before calling

def check_enum(setting_name, value, allowed):
    if value not in allowed:
        raise ValueError('%s=%r not in allowed %s' % (setting_name, value, sorted(allowed)))
    return value

Type guard

def is_valid_enum_value(value, allowed: set) -> bool:
    return value in allowed

Try / catch

try:
    enum_type.ValidateMSBuild(my_value)
except ValueError:
    # fall back to a known-safe label or drop the setting
    my_value = next(iter(enum_type._msbuild_values))
    enum_type.ValidateMSBuild(my_value)

Prevention

When it happens

Trigger: Passing a string keyword (e.g. 'MaxSpeed') to a setting whose MSBuild enumeration only lists certain labels; passing a label from a newer/older VS version than the one gyp targets.

Common situations: Copy-pasting an MSBuild value from a .vcxproj generated by a different VS version; typo in an enumeration keyword; using a value that is valid for MSVS indices but not for MSBuild labels.

Related errors


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