{"record":{"id":"fec26c90ba3a87ef","repo":"nodejs/node","slug":"expected-string-got-r","errorCode":null,"errorMessage":"expected string; got %r","messagePattern":"expected string; got %r","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/MSVSSettings.py","lineNumber":110,"sourceCode":"\n        Args:\n          value: the MSVS value to convert.\n\n        Returns:\n          the MSBuild equivalent.\n\n        Raises:\n          ValueError if value is not valid.\n        \"\"\"\n        return value\n\n\nclass _String(_Type):\n    \"\"\"A setting that's just a string.\"\"\"\n\n    def ValidateMSVS(self, value):\n        if not isinstance(value, str):\n            raise ValueError(\"expected string; got %r\" % value)\n\n    def ValidateMSBuild(self, value):\n        if not isinstance(value, str):\n            raise ValueError(\"expected string; got %r\" % value)\n\n    def ConvertToMSBuild(self, value):\n        # Convert the macros\n        return ConvertVCMacrosToMSBuild(value)\n\n\nclass _StringList(_Type):\n    \"\"\"A settings that's a list of strings.\"\"\"\n\n    def ValidateMSVS(self, value):\n        if not isinstance(value, (list, str)):\n            raise ValueError(\"expected string list; got %r\" % value)\n\n    def ValidateMSBuild(self, value):","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/MSVSSettings.py#L92-L128","documentation":"_String.ValidateMSVS in MSVSSettings.py raises ValueError('expected string; got %r') when the value supplied for an MSVS setting whose declared type is _String is not a Python str. Gyp validates each msvs_settings entry against a type table; the _String type only accepts str, rejecting ints, bools, lists, or None. This guards the gyp -> .vcproj conversion from emitting malformed XML attributes.","triggerScenarios":"A gyp file sets an MSVS string setting to a non-string YAML/JSON-like value, e.g. 'Optimization': 2 (int) or 'AdditionalIncludeDirectories': None; the msvs_settings dict is assembled programmatically and a number slips through where the schema expects a string macro like \"$(IntDir)\".","commonSituations":"Migrating a .gyp from another generator (make/ninja) where ints were tolerated; copy-pasting MSBuild-style boolean True/False into an MSVS-only setting; downstream tooling that emits numeric optimization levels.","solutions":["Inspect the named setting in the failing msvs_settings dict and coerce the value to str: str(value).","Match the documented MSVS value format (e.g. Optimization expects \"0\"/\"1\"/\"2\"/\"3\"/\"4\" as strings, not ints).","If the value is genuinely optional, omit the key instead of passing None.","Run gyp with --debug general to see which target/setting triggered the validator."],"exampleFix":"# before\n'Optimization': 2,\n\n# after\n'Optimization': '2',","handlingStrategy":"type-guard","validationCode":"def coerce_string_setting(value):\n    if value is None:\n        return None  # caller should omit key\n    if not isinstance(value, str):\n        raise TypeError('MSVS string setting expects str, got %r' % type(value))\n    return value","typeGuard":"def is_msvs_string(value) -> bool:\n    return isinstance(value, str)","tryCatchPattern":"try:\n    _string.ValidateMSVS(my_value)\nexcept ValueError:\n    my_value = str(my_value)  # or omit the setting\n    _string.ValidateMSVS(my_value)","preventionTips":["Quote all MSVS string settings in .gyp files; never rely on implicit int->str.","For optional settings, omit the key rather than passing None.","Run gyp with --debug general to surface the failing setting name quickly."],"tags":["gyp","msvs","validation","type-check","settings"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}