{"record":{"id":"7a36d4cbbd4de309","repo":"nodejs/node","slug":"expected-bool-got-r","errorCode":null,"errorMessage":"expected bool; got %r","messagePattern":"expected bool; got %r","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/MSVSSettings.py","lineNumber":145,"sourceCode":"\n    def ValidateMSBuild(self, value):\n        if not isinstance(value, (list, str)):\n            raise ValueError(\"expected string list; got %r\" % value)\n\n    def ConvertToMSBuild(self, value):\n        # Convert the macros\n        if isinstance(value, list):\n            return [ConvertVCMacrosToMSBuild(i) for i in value]\n        else:\n            return ConvertVCMacrosToMSBuild(value)\n\n\nclass _Boolean(_Type):\n    \"\"\"Boolean settings, can have the values 'false' or 'true'.\"\"\"\n\n    def _Validate(self, value):\n        if value not in {\"true\", \"false\"}:\n            raise ValueError(\"expected bool; got %r\" % value)\n\n    def ValidateMSVS(self, value):\n        self._Validate(value)\n\n    def ValidateMSBuild(self, value):\n        self._Validate(value)\n\n    def ConvertToMSBuild(self, value):\n        self._Validate(value)\n        return value\n\n\nclass _Integer(_Type):\n    \"\"\"Integer settings.\"\"\"\n\n    def __init__(self, msbuild_base=10):\n        _Type.__init__(self)\n        self._msbuild_base = msbuild_base","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/MSVSSettings.py#L127-L163","documentation":"_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.","triggerScenarios":"Passing Python True/False (bool), 1/0 (int), 'True'/'False' (wrong case), or 'yes'/'no' to a setting registered as _Boolean.","commonSituations":"Developers writing gyp files instinctively use Python True/False; copying values from documentation that capitalizes them; converting from a system that uses 0/1.","solutions":["Use the lowercase string literals 'true' or 'false' in the setting value.","If computing the value, map it explicitly: 'true' if flag else 'false'.","Audit the setting name in MSVSSettings to confirm it is registered as _Boolean."],"exampleFix":"# before\n'GenerateManifest': True,\n\n# after\n'GenerateManifest': 'true',","handlingStrategy":"type-guard","validationCode":"def to_msvs_bool(value):\n    if isinstance(value, bool):\n        return 'true' if value else 'false'\n    if value in ('true', 'false'):\n        return value\n    raise ValueError('expected true/false, got %r' % value)","typeGuard":"def is_msvs_bool_string(value) -> bool:\n    return value in ('true', 'false')","tryCatchPattern":"try:\n    _boolean.ValidateMSBuild(my_flag)\nexcept ValueError:\n    my_flag = to_msvs_bool(my_flag)\n    _boolean.ValidateMSBuild(my_flag)","preventionTips":["Always use the lowercase string literals 'true'/'false' in gyp settings.","Run Python bool values through a 'true'/'false' mapper before assigning.","Add a lint rule in your gyp loader that rejects bool/int for _Boolean settings."],"tags":["gyp","msvs","msbuild","validation","boolean","type-check"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}