nodejs/node · error · GypError
Call to '%s' returned exit status %d while in %s.
Error message
Call to '%s' returned exit status %d while in %s.
What it means
For <!() command expansions, GYP runs the command via subprocess.run and, if result.returncode is greater than zero, raises this GypError with the command, the exit status, and the build file. stderr is intentionally not captured so it streams to the console, which usually tells you why the command failed. The command's stdout (only produced on success) is what gets substituted.
Source
Thrown at tools/gyp/pylib/gyp/input.py:976
# Fix up command with platform specific workarounds.
contents = FixupPlatformCommand(contents)
try:
# stderr will be printed no matter what
result = subprocess.run(
contents,
stdout=subprocess.PIPE,
shell=use_shell,
cwd=build_file_dir,
check=False,
)
except Exception as e:
raise GypError(
"%s while executing command '%s' in %s"
% (e, contents, build_file)
)
if result.returncode > 0:
raise GypError(
"Call to '%s' returned exit status %d while in %s."
% (contents, result.returncode, build_file)
)
replacement = result.stdout.decode("utf-8").rstrip()
cached_command_results[cache_key] = replacement
else:
gyp.DebugOutput(
gyp.DEBUG_VARIABLES,
"Had cache value for command '%s' in directory '%s'",
contents,
build_file_dir,
)
replacement = cached_value
elif contents not in variables:
if contents[-1] in ["!", "/"]:
# In order to allow cross-compiles (nacl) to happen more naturally,View on GitHub (pinned to 1b2de5e052)
Solutions
- Look immediately above the GypError in the log — stderr was printed live and explains the failure.
- Re-run the exact command (from the .gyp file's directory) to reproduce and fix the underlying tool/script.
- Make the command tolerant of missing inputs if that is intended, or fix the inputs so it succeeds.
- Ensure required env vars are exported before invoking gyp.
Example fix
// before — script exits 1 on missing template 'version': '<!(./gen_version.py)', // after — pass the template path the script expects 'version': '<!(./gen_version.py --template ./tmpl.h)',
Defensive patterns
Strategy: validation
Validate before calling
import subprocess
rc = subprocess.run(cmd, shell=True, cwd=build_file_dir).returncode
assert rc == 0, f'<!() command exited {rc}: {cmd}' Type guard
def command_succeeds(cmd: str, cwd: str) -> bool:
import subprocess
return subprocess.run(cmd, shell=True, cwd=cwd).returncode == 0 Try / catch
try:
gyp.process_build_file(...)
except gyp.input.GypError as e:
if 'returned exit status' in str(e):
log_full_stderr_context(e) Prevention
- Treat <!() commands as part of the build — test them in CI like any other step.
- Make codegen scripts exit non-zero only on real errors, never on warnings, to keep gyp green.
- Set required env vars (PATH, OUT_DIR, etc.) in the gyp wrapper script.
When it happens
Trigger: A '<!(cmd)' expansion runs a script/program that exits non-zero — the codegen tool failed, the script hit an internal error, missing input file, wrong CLI flags, or a flaky network call inside the command.
Common situations: A codegen script that errors on missing input; wrong CLI flags after a tool upgrade; a script that depends on env vars (PATH, OUT_DIR) not set in the gyp environment; flaky commands during distributed builds; a helper that returns non-zero on warnings-as-errors.
Related errors
- %s while executing command '%s' in %s
- Unknown command string '%s' in '%s'.
- | cannot handle absolute paths, got "%s"
- Error importing pymod_do_mainmodule (%s): %s
- Undefined variable %s in %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/c8ab14e521b680e1.
Report an issue: GitHub.