bazelbuild/bazel · critical · AssertionError
Could not find python binary: {PYTHON_BINARY}
Error message
Could not find python binary: {PYTHON_BINARY} What it means
Final guard in the Python launcher: FindPythonBinary(module_space) returned None, so the interpreter named by PYTHON_BINARY could not be located via runfiles, absolute path, repo-relative path, or PATH search. The AssertionError echoes the configured PYTHON_BINARY value so you can see what was searched for.
Source
Thrown at tools/python/python_bootstrap_template.txt:502
new_env['PYTHONPATH'] = python_path
runfiles_envkey, runfiles_envvalue = RunfilesEnvvar(module_space)
if runfiles_envkey:
new_env[runfiles_envkey] = runfiles_envvalue
# Don't prepend a potentially unsafe path to sys.path
# See: https://docs.python.org/3.11/using/cmdline.html#envvar-PYTHONSAFEPATH
new_env['PYTHONSAFEPATH'] = '1'
main_filename = os.path.join(module_space, main_rel_path)
main_filename = GetWindowsPathWithUNCPrefix(main_filename)
assert os.path.exists(main_filename), \
'Cannot exec() %r: file not found.' % main_filename
assert os.access(main_filename, os.R_OK), \
'Cannot exec() %r: file not readable.' % main_filename
program = python_program = FindPythonBinary(module_space)
if python_program is None:
raise AssertionError('Could not find python binary: ' + PYTHON_BINARY)
# COVERAGE_DIR is set if coverage is enabled and instrumentation is configured
# for something, though it could be another program executing this one or
# one executed by this one (e.g. an extension module).
if os.environ.get('COVERAGE_DIR'):
cov_tool = FindCoverageEntryPoint(module_space)
if cov_tool is None:
PrintVerboseCoverage('Coverage was enabled, but python coverage tool was not configured.')
else:
# Inhibit infinite recursion:
if 'PYTHON_COVERAGE' in os.environ:
del os.environ['PYTHON_COVERAGE']
if not os.path.exists(cov_tool):
raise EnvironmentError(
'Python coverage tool %r not found. '
'Try running with VERBOSE_COVERAGE=1 to collect more information.'
% cov_toolView on GitHub (pinned to e6e199d060)
Solutions
- Check the PYTHON_BINARY value in the message: if it is a name, ensure that interpreter exists on PATH of the environment where the binary runs.
- If it is a path, verify the file exists (absolute) or is present under the runfiles root (repo-relative).
- Install the required interpreter in the execution environment or point --python_path/--python_top at a valid absolute interpreter.
Example fix
# before bazel build //my:tool --python_path=python3.11 # not installed # after bazel build //my:tool --python_path=/usr/bin/python3 # verified absolute interpreter
Defensive patterns
Strategy: validation
Validate before calling
import shutil, os
assert os.path.isabs(PYTHON_BINARY) and os.path.exists(PYTHON_BINARY) or shutil.which(PYTHON_BINARY), \
'interpreter %r unavailable' % PYTHON_BINARY Prevention
- Pin --python_path to an absolute interpreter path that exists in the execution environment.
- For containers/CI, install the interpreter and verify 'python3 --version' before running bazel-built tools.
When it happens
Trigger: PYTHON_BINARY is a bare name (e.g. 'python3') not present on PATH of the execution environment; a repo-relative interpreter path that does not exist in the runfiles; the interpreter's runfiles entry missing because its target is not in the stub's deps.
Common situations: Running a bazel-built python binary in a container/VM without the interpreter installed; PATH stripped in the action's env; --python_path pointing at a nonexistent interpreter; sandboxed execution removing PATH entries.
Related errors
- Bazel does not support execution of Python interpreters via
- Cannot find .runfiles directory for %s
- Python coverage tool %r not found. Try running with VERBOSE_
- Unsupported JUnit Runner API version ${JUNIT_API_VERSION_PRO
- No filter expression specified after ${arg}
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/bd21f883f4978bc6.
Report an issue: GitHub.