nodejs/node · error · Exception
{} not supported (target {}).
Error message
{} not supported (target {}). What it means
msvs_emulation.MsvsSettings checks a set of MSVS-only fields (the 'unsupported_fields' list, which includes 'msvs_postbuild') against each configuration. When using a non-MSVS generator (typically ninja), these fields have no meaning, so each occurrence is reported as unsupported and the accumulated list is raised as a single Exception.
Source
Thrown at tools/gyp/pylib/gyp/msvs_emulation.py:240
getattr(self, field)[configname] = config.get(field, default())
self.msvs_cygwin_dirs = spec.get("msvs_cygwin_dirs", ["."])
unsupported_fields = [
"msvs_prebuild",
"msvs_postbuild",
]
unsupported = []
for field in unsupported_fields:
for config in configs.values():
if field in config:
unsupported += [
"{} not supported (target {}).".format(
field, spec["target_name"]
)
]
if unsupported:
raise Exception("\n".join(unsupported))
def GetExtension(self):
"""Returns the extension for the target, with no leading dot.
Uses 'product_extension' if specified, otherwise uses MSVS defaults based on
the target type.
"""
ext = self.spec.get("product_extension", None)
return ext or gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "")
def GetVSMacroEnv(self, base_to_build=None, config=None):
"""Get a dict of variables mapping internal VS macro names to their gyp
equivalents."""
target_arch = self.GetArch(config)
target_platform = "Win32" if target_arch == "x86" else target_arch
target_name = self.spec.get("product_prefix", "") + self.spec.get(
"product_name", self.spec["target_name"]
)View on GitHub (pinned to 1b2de5e052)
Solutions
- Remove the offending MSVS-only field(s) from the configuration(s) of that target.
- If you need the equivalent behavior under ninja, express it via generator-agnostic keys (e.g. postbuild steps via 'actions' or linker flags).
- Re-run gyp with the ninja generator.
Example fix
// before
'configurations': {
'Release': { 'msvs_postbuild': 'echo done' }
}
// after
'configurations': {
'Release': { }
}
// and, if needed, add a generator-agnostic action or linker flag Defensive patterns
Strategy: validation
Validate before calling
UNSUPPORTED = {'msvs_postbuild'} # extend to match unsupported_fields
for cfg_name, cfg in target_dict.get('configurations', {}).items():
bad = UNSUPPORTED & set(cfg)
if bad and using_ninja:
raise ValueError(f'{target_dict["target_name"]}: {bad} unsupported under ninja') Type guard
def no_unsupported_msvs_fields(target_dict: dict, generator: str) -> bool:
if generator == 'ninja':
bad = {'msvs_postbuild'}
return all(not (bad & set(cfg)) for cfg in target_dict.get('configurations', {}).values())
return True Prevention
- Keep MSVS-only keys only in builds that use the msvs generator.
- When porting to ninja, audit target dicts for msvs_* keys.
- Use conditions keyed on the generator to gate msvs-specific fields.
When it happens
Trigger: A target spec contains one of the unsupported_fields keys (e.g. msvs_postbuild) inside one of its configurations, and the build uses the ninja (or other non-msvs) generator that routes through msvs_emulation.
Common situations: Copying MSVS-specific settings from a Visual Studio build into a target that is now built with ninja; leftover msvs_postbuild from a porting effort.
Related errors
- AddFileConfig: file "%s" not in project.
- expected string; got %r
- expected string list; got %r
- expected bool; got %r
- index value (%d) not in expected range [0, %d)
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/1c4d32e40c6f9592.
Report an issue: GitHub.