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_tool

View on GitHub (pinned to e6e199d060)

Solutions

  1. 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.
  2. If it is a path, verify the file exists (absolute) or is present under the runfiles root (repo-relative).
  3. 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

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


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/bd21f883f4978bc6. Report an issue: GitHub.