nodejs/node · error · GypError
Error importing pymod_do_mainmodule (%s): %s
Error message
Error importing pymod_do_mainmodule (%s): %s
What it means
The <!pymod_do_main(modulename args) expansion tells GYP to import a Python module and call its DoMain(args) function to produce the replacement text. When __import__(modulename) raises ImportError, GYP wraps it in this GypError naming the offending module and the underlying import error. The module is imported from build_file_dir appended to sys.path, so it must be importable from there.
Source
Thrown at tools/gyp/pylib/gyp/input.py:941
replacement = ""
if command_string == "pymod_do_main":
# <!pymod_do_main(modulename param eters) loads |modulename| as a
# python module and then calls that module's DoMain() function,
# passing ["param", "eters"] as a single list argument. For modules
# that don't load quickly, this can be faster than
# <!(python modulename param eters). Do this in |build_file_dir|.
oldwd = os.getcwd() # Python doesn't like os.open('.'): no fchdir.
if build_file_dir: # build_file_dir may be None (see above).
os.chdir(build_file_dir)
sys.path.append(os.getcwd())
try:
parsed_contents = shlex.split(contents)
try:
py_module = __import__(parsed_contents[0])
except ImportError as e:
raise GypError(
"Error importing pymod_do_main"
"module (%s): %s" % (parsed_contents[0], e)
)
replacement = str(
py_module.DoMain(parsed_contents[1:])
).rstrip()
finally:
sys.path.pop()
os.chdir(oldwd)
assert replacement is not None
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)View on GitHub (pinned to 1b2de5e052)
Solutions
- Confirm the module file exists in the build_file_dir (or on sys.path) and the name matches parsed_contents[0] exactly.
- Run 'python -c "import modulename"' from the build_file_dir to reproduce the ImportError and read the underlying message in the GypError text.
- Install any missing third-party dependency the helper imports, or vendor it next to the helper.
- Fix typos/shlex artifacts in the <!pymod_do_main(...) expression (the first whitespace-delimited token is the module name).
Example fix
// before 'value': '<!pymod_do_main(build_helper get_version) main', // after — ensure build_helper.py lives next to the .gyp file: // <gyp dir>/build_helper.py exporting def DoMain(args): ... 'value': '<!pymod_do_main(build_helper get_version) main',
Defensive patterns
Strategy: validation
Validate before calling
# From the build_file_dir, confirm the helper module imports cleanly before running gyp.
import sys, os
sys.path.insert(0, build_file_dir)
try:
__import__(module_name)
except ImportError as e:
raise SystemExit(f"pymod_do_main helper {module_name!r} is not importable: {e}") Type guard
def is_pymod_importable(module_name: str, build_file_dir: str) -> bool:
import importlib.util
spec = importlib.util.find_spec(module_name)
return spec is not None Prevention
- Run 'python -c "import helper"' from the .gyp file's directory as a pre-build sanity check.
- Keep pymod_do_main helpers next to the .gyp file or vendor them on a known sys.path entry.
- Pin the helper's own dependencies in the same environment gyp runs in.
When it happens
Trigger: A .gyp file uses '<!(pymod_do_main mymodule arg1)' (or the <! shorthand) but 'mymodule' is not on sys.path, has a typo in its name, has a syntax error, or itself imports an unavailable dependency. Also triggers when the module's name parses differently via shlex.split (e.g. stray quotes).
Common situations: Missing PYTHONPATH entry for a helper script shipped alongside the .gyp file; a helper module that was renamed across a refactor; a Python 2/3 incompatibility in the helper; a helper that imports a third-party package not installed in the gyp-running environment (e.g. a v8/node build helper).
Related errors
- | cannot handle absolute paths, got "%s"
- Unknown command string '%s' in '%s'.
- %s while executing command '%s' in %s
- Call to '%s' returned exit status %d while in %s.
- Undefined variable %s in %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/61899d9d050b036c.
Report an issue: GitHub.