nodejs/node · error · GypError

%s while executing command '%s' in %s

Error message

%s while executing command '%s' in %s

What it means

When a <!() (or >!) shell-command expansion is evaluated, GYP runs the command via subprocess.run with shell=use_shell and cwd=build_file_dir. If subprocess.run itself raises (e.g. FileNotFoundError because the executable is missing, or a permission error spawning the process), GYP wraps that exception in this GypError, embedding the exception, the command string, and the build file. This is distinct from a non-zero exit code (see error 484).

Source

Thrown at tools/gyp/pylib/gyp/input.py:970

                elif command_string:
                    raise GypError(
                        "Unknown command string '%s' in '%s'."
                        % (command_string, contents)
                    )
                else:
                    # 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,

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Read the embedded exception text — FileNotFoundError means the executable is not on PATH, so install it or fix the path.
  2. If using the array form '<!@[cmd, args]', make sure every element is a real argv entry and the command resolves absolutely.
  3. Verify build_file_dir (the .gyp file's directory) exists and is accessible from gyp's cwd.
  4. Run the exact command string manually from the .gyp file's directory to reproduce the spawn failure.

Example fix

// before — 'my_codegen' not on PATH
'sources': ['<!(my_codegen --list)'],
// after — point at the script's real location or install it
'sources': ['<!(./tools/my_codegen --list)'],
Defensive patterns

Strategy: validation

Validate before calling

import shutil, os
for tool in required_tools:
    assert shutil.which(tool) or os.path.exists(tool), f'Tool for <() expansion not found: {tool}'

Type guard

def is_command_runnable(cmd: str, cwd: str) -> bool:
    import shutil, os
    first = shutil._which if False else __import__('shlex').split(cmd)[0]
    return bool(__import__('shutil').which(first)) and os.path.isdir(cwd or '.')

Try / catch

try:
    gyp.process_build_file(...)
except gyp.input.GypError as e:
    if 'while executing command' in str(e):
        diagnose_missing_tool(str(e))

Prevention

When it happens

Trigger: The command referenced by '<!(foo args)' names an executable not present on PATH; the command string is malformed so the shell cannot spawn; the working directory build_file_dir does not exist or is not readable; the OS refuses to spawn (permissions, OOM, too many fds).

Common situations: Forgetting to install a build-time code generator (protoc, gperf, a vendored script); running gyp in an environment without a required tool on PATH; a path with spaces or shell metacharacters breaking the spawn when use_shell is False (array form); a stale build_file_dir after a tree reorganization.

Related errors


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