nodejs/node · critical · Exception

"%s" failed with error %d

Error message

"%s" failed with error %d

What it means

To capture the MSVC environment for ninja, gyp runs vs.SetupScript(arch) followed by '&& set' via subprocess.Popen and checks popen.returncode. A non-zero return code means the VS environment setup itself failed; gyp raises with the failing command and its exit code for diagnosis.

Source

Thrown at tools/gyp/pylib/gyp/msvs_emulation.py:1194

    generation and use custom environment files prepared by yourself."""
    archs = ("x86", "x64", "arm64")
    if generator_flags.get("ninja_use_custom_environment_files", 0):
        cl_paths = {}
        for arch in archs:
            cl_paths[arch] = "cl.exe"
        return cl_paths
    vs = GetVSVersion(generator_flags)
    cl_paths = {}
    for arch in archs:
        # Extract environment variables for subprocesses.
        args = vs.SetupScript(arch)
        args.extend(("&&", "set"))
        popen = subprocess.Popen(
            args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
        )
        variables = popen.communicate()[0].decode("utf-8")
        if popen.returncode != 0:
            raise Exception('"%s" failed with error %d' % (args, popen.returncode))
        env = _ExtractImportantEnvironment(variables)

        # Inject system includes from gyp files into INCLUDE.
        if system_includes:
            system_includes = system_includes | OrderedSet(
                env.get("INCLUDE", "").split(";")
            )
            env["INCLUDE"] = ";".join(system_includes)

        env_block = _FormatAsEnvironmentBlock(env)
        f = open_out(os.path.join(toplevel_build_dir, "environment." + arch), "w")
        f.write(env_block)
        f.close()

        # Find cl.exe location for this architecture.
        args = vs.SetupScript(arch)
        args.extend(
            ("&&", "for", "%i", "in", "(cl.exe)", "do", "@echo", "LOC:%~$PATH:i")

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Run the exact command shown in the error message by hand to see the underlying error text from vcvarsall.bat.
  2. Confirm the requested architecture (e.g. x64) and VS version are actually installed.
  3. Install/repair the Visual Studio C++ Build Tools and the matching Windows SDK.
  4. Point GYP_MSVS_VERSION at an installed version, or let gyp auto-detect.

Example fix

// before
// gyp fails: "vcvarsall.bat x64 && set" failed with error 1
// diagnose
// $ cmd /c "C:\Program Files (x86)\...\vcvarsall.bat x64"
// fix: install x64 build tools, then
// $ set GYP_MSVS_VERSION=2022
// $ gyp --depth=. my.gyp
Defensive patterns

Strategy: try-catch

Validate before calling

# Probe the VS setup script standalone before driving a full gyp run.
args = vs.SetupScript(arch) + ['&&', 'set']
rc = subprocess.run(args, shell=True, stdout=subprocess.DEVNULL).returncode
if rc != 0:
    raise RuntimeError(f'VS setup script exited {rc}; install/repair the {arch} toolchain')

Type guard

def vs_setup_succeeds(vs, arch) -> bool:
    args = vs.SetupScript(arch) + ['&&', 'set']
    return subprocess.run(args, shell=True, stdout=subprocess.DEVNULL).returncode == 0

Try / catch

try:
    env = _GenerateEnvironment(...)
except Exception as e:
    if 'failed with error' in str(e):
        # Surface the failing command and run it manually for the real error.
        print('VS environment setup failed; run the command in the error manually.', file=sys.stderr)
    raise

Prevention

When it happens

Trigger: The combined 'vcvarsall.bat <arch> && set' (or equivalent setup script) exits with a non-zero status when gyp invokes it to build environment.<arch>.

Common situations: The requested VS version/architecture is not installed; vcvarsall.bat errors due to a missing Windows SDK; GYP_MSVS_VERSION selects a toolchain that was uninstalled; running on a system where the VS command prompt shortcut resolves differently.

Related errors


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