nodejs/node · error · RuntimeError
No libnode.so to install!
Error message
No libnode.so to install!
What it means
When node is built as a shared library (configure variable node_shared=true, on non-Windows/non-z/OS), tools/install.py looks for the built libnode.<shlib_suffix> in build_dir/ and build_dir/lib/ (ninja vs make output locations). If neither exists it raises RuntimeError, because there is no artifact to install.
Source
Thrown at tools/install.py:194
# install libnode.version.so
so_name = 'libnode.' + re.sub(r'\.x$', '.so', options.variables.get('shlib_suffix'))
action(options, [os.path.join(output_prefix, so_name)], options.variables.get('libdir') + '/' + so_name)
# create symlink of libnode.so -> libnode.version.so (C++ addons compat)
link_path = abspath(options.install_path, 'lib/libnode.so')
try_symlink(options, so_name, link_path)
else:
# Ninja and Makefile generators output the library in different directories;
# find out which one we have, and install first found
output_lib_name = 'libnode.' + options.variables.get('shlib_suffix')
output_lib_candidate_paths = [
os.path.join(options.build_dir, output_lib_name),
os.path.join(options.build_dir, "lib", output_lib_name),
]
try:
output_lib = next(filter(os.path.exists, output_lib_candidate_paths))
except StopIteration as not_found:
raise RuntimeError("No libnode.so to install!") from not_found
action(options, [output_lib],
os.path.join(options.variables.get('libdir'), output_lib_name))
action(options, [os.path.join(options.v8_dir, 'tools/gdbinit')], 'share/doc/node/')
action(options, [os.path.join(options.v8_dir, 'tools/lldb_commands.py')], 'share/doc/node/')
if 'openbsd' in sys.platform:
action(options, ['doc/node.1'], 'man/man1/')
else:
action(options, ['doc/node.1'], 'share/man/man1/')
if 'true' == options.variables.get('node_install_npm'):
npm_files(options, action)
if 'true' == options.variables.get('node_install_corepack'):
corepack_files(options, action)
headers(options, action)View on GitHub (pinned to 1b2de5e052)
Solutions
- Build the shared library first with the same configuration, e.g. `make -j$(nproc) out/Release/libnode.so.71` (match your shlib_suffix).
- Verify the artifact exists: `ls out/Release/libnode.* out/Release/lib/libnode.*`.
- Pass the correct --build-dir (the directory that actually contains the built lib).
Example fix
// before python tools/install.py install --build-dir=out/Debug # never built Debug // after make -j$(nproc) out/Release/libnode.so.71 python tools/install.py install --build-dir=out/Release
Defensive patterns
Strategy: validation
Validate before calling
import os, glob
bd=options.build_dir; suf=options.variables.get('shlib_suffix')
cands=[os.path.join(bd,f'libnode.{suf}'), os.path.join(bd,'lib',f'libnode.{suf}')]
assert any(os.path.exists(c) for c in cands), f'no libnode.{suf} in {bd}' Prevention
- Always build before install, using the same build_dir you pass to install.py.
- Confirm shlib_suffix matches the file the generator actually produced.
When it happens
Trigger: Running `python tools/install.py install` (or `make install`) with a --shared configuration but without first building, or with --build-dir pointing somewhere the lib was never written.
Common situations: Forgot to run the build; built into out/Release but installed with default/Debug build_dir; build failed silently; shlib_suffix variable mismatch; the lib landed in an uncovered output dir.
Related errors
- Environment variable ZOSLIB_INCLUDES is not set
- Bad command: %s
- Could not find executable. Should be
- --enable-v8windbg is incompatible with --without-bundled-v8.
- --v8-enable-hugepage is supported only on linux.
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/04fedff496f9ab5b.
Report an issue: GitHub.