nodejs/node · error · RuntimeError
Failed to find //buildtools directory for checkdeps
Error message
Failed to find //buildtools directory for checkdeps
What it means
V8's PRESUBMIT.py wires up the checkdeps include-rule linter by locating the //buildtools/checkdeps package. It looks for a 'buildtools' dir in the current presubmit path, then one level up; if neither exists it raises RuntimeError because checkdeps can't be imported and dependency rules can't be evaluated.
Source
Thrown at deps/v8/PRESUBMIT.py:179
return results
def _CheckUnwantedDependencies(input_api, output_api):
"""Runs checkdeps on #include statements added in this
change. Breaking - rules is an error, breaking ! rules is a
warning.
"""
# We need to wait until we have an input_api object and use this
# roundabout construct to import checkdeps because this file is
# eval-ed and thus doesn't have __file__.
original_sys_path = sys.path
try:
root = input_api.PresubmitLocalPath()
if not os.path.exists(os.path.join(root, 'buildtools')):
root = os.path.dirname(root)
if not os.path.exists(os.path.join(root, 'buildtools')):
raise RuntimeError(
"Failed to find //buildtools directory for checkdeps")
sys.path = sys.path + [
input_api.os_path.join(root, 'buildtools', 'checkdeps')
]
import checkdeps
from cpp_checker import CppChecker
from rules import Rule
finally:
# Restore sys.path to what it was before.
sys.path = original_sys_path
def _FilesImpactedByDepsChange(files):
all_files = [f.AbsoluteLocalPath() for f in files]
deps_files = [p for p in all_files if IsDepsFile(p)]
impacted_files = union([_CollectImpactedFiles(path) for path in deps_files])
impacted_file_objs = [ImpactedFile(path) for path in impacted_files]
return impacted_file_objs
View on GitHub (pinned to 1b2de5e052)
Solutions
- Run `gclient sync` (or `gclient sync --deps=v8`) so buildtools is fetched next to v8.
- Run the presubmit from the repo root that actually contains buildtools, not a subdirectory.
- If you vendored v8 manually, also vendor the matching buildtools directory at the expected level.
Example fix
# before: standalone v8 checkout without DEPS python deps/v8/PRESUBMIT.py # after gclient sync python deps/v8/PRESUBMIT.py
Defensive patterns
Strategy: validation
Validate before calling
import os root = os.getcwd() assert os.path.isdir(os.path.join(root,'buildtools')) or os.path.isdir(os.path.join(os.path.dirname(root),'buildtools')), 'run gclient sync to fetch buildtools before presubmit'
Prevention
- Always `gclient sync` so buildtools is fetched alongside v8.
- Run PRESUBMIT.py from the checkout root that owns buildtools.
When it happens
Trigger: Raised in _CheckNoApiUsage/_CheckDeps when `os.path.exists(input_api.PresubmitLocalPath()/buildtools)` and `os.path.exists(dirname(PresubmitLocalPath())/buildtools)` are both false — i.e. the presubmit is run from a checkout that doesn't contain buildtools.
Common situations: Running V8's presubmit on a standalone V8 checkout fetched without its DEPS (gclient sync skipped); running PRESUBMIT.py from inside Node's deps/v8 where buildtools lives at the Node root, two levels up, not one; vendoring V8 into another repo without bringing buildtools along.
Related errors
- --enable-v8windbg is incompatible with --without-bundled-v8.
- --v8-enable-hugepage is supported only on linux.
- Only one of the --v8-enable-object-print or --v8-disable-obj
- Only one of the --v8-enable-temporal-support or --v8-disable
- Missing libffi target header: {ffitarget_src}
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/d4b743d4569abdeb.
Report an issue: GitHub.