nodejs/node · error · ValueError

expected bool; got %r

Error message

expected bool; got %r

What it means

_Boolean._Validate raises ValueError('expected bool; got %r') when a boolean-typed MSVS/MSBuild setting is given a value that is not exactly the string 'true' or 'false'. Note these are the lowercase strings, not Python bools (True/False) and not 'True'/'False'. Gyp stores booleans as those literal strings because they map directly to MSBuild XML attribute values.

Solutions

  1. Use the lowercase string literals 'true' or 'false' in the setting value.
  2. If computing the value, map it explicitly: 'true' if flag else 'false'.
  3. Audit the setting name in MSVSSettings to confirm it is registered as _Boolean.

Example fix

# before
'GenerateManifest': True,

# after
'GenerateManifest': 'true',
Defensive patterns

Strategy: type-guard

Validate before calling

def to_msvs_bool(value):
    if isinstance(value, bool):
        return 'true' if value else 'false'
    if value in ('true', 'false'):
        return value
    raise ValueError('expected true/false, got %r' % value)

Type guard

def is_msvs_bool_string(value) -> bool:
    return value in ('true', 'false')

Try / catch

try:
    _boolean.ValidateMSBuild(my_flag)
except ValueError:
    my_flag = to_msvs_bool(my_flag)
    _boolean.ValidateMSBuild(my_flag)

Prevention

When it happens

Trigger: Passing Python True/False (bool), 1/0 (int), 'True'/'False' (wrong case), or 'yes'/'no' to a setting registered as _Boolean.

Common situations: Developers writing gyp files instinctively use Python True/False; copying values from documentation that capitalizes them; converting from a system that uses 0/1.

Related errors


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

Appendix: source

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

    def ValidateMSBuild(self, value):
        if not isinstance(value, (list, str)):
            raise ValueError("expected string list; got %r" % value)

    def ConvertToMSBuild(self, value):
        # Convert the macros
        if isinstance(value, list):
            return [ConvertVCMacrosToMSBuild(i) for i in value]
        else:
            return ConvertVCMacrosToMSBuild(value)


class _Boolean(_Type):
    """Boolean settings, can have the values 'false' or 'true'."""

    def _Validate(self, value):
        if value not in {"true", "false"}:
            raise ValueError("expected bool; got %r" % value)

    def ValidateMSVS(self, value):
        self._Validate(value)

    def ValidateMSBuild(self, value):
        self._Validate(value)

    def ConvertToMSBuild(self, value):
        self._Validate(value)
        return value


class _Integer(_Type):
    """Integer settings."""

    def __init__(self, msbuild_base=10):
        _Type.__init__(self)
        self._msbuild_base = msbuild_base

View on GitHub (pinned to 1b2de5e052)