bazelbuild/bazel · error · AssertionError

Cannot find .runfiles directory for %s

Error message

Cannot find .runfiles directory for %s

What it means

Raised in the Python launcher stub while locating the .runfiles directory: it repeatedly matches the stub filename against a '*_runfiles' pattern and follows symlinks. If neither the pattern nor symlink traversal yields a runfiles dir, it raises AssertionError naming sys.argv[0].

Source

Thrown at tools/python/python_bootstrap_template.txt:172

  while True:
    module_space = stub_filename + ('.exe' if IsWindows() else '') + '.runfiles'
    if os.path.isdir(module_space):
      return module_space

    runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if IsWindows() else '/') + '.*'
    matchobj = re.match(runfiles_pattern, stub_filename)
    if matchobj:
      return matchobj.group(1)

    if not os.path.islink(stub_filename):
      break
    target = os.readlink(stub_filename)
    if os.path.isabs(target):
      stub_filename = target
    else:
      stub_filename = os.path.join(os.path.dirname(stub_filename), target)

  raise AssertionError('Cannot find .runfiles directory for %s' % sys.argv[0])

def ExtractZip(zip_path, dest_dir):
  """Extracts the contents of a zip file, preserving the unix file mode bits.

  These include the permission bits, and in particular, the executable bit.

  Ideally the zipfile module should set these bits, but it doesn't. See:
  https://bugs.python.org/issue15795.

  Args:
      zip_path: The path to the zip file to extract
      dest_dir: The path to the destination directory
  """
  zip_path = GetWindowsPathWithUNCPrefix(zip_path)
  dest_dir = GetWindowsPathWithUNCPrefix(dest_dir)
  with zipfile.ZipFile(zip_path) as zf:
    for info in zf.infolist():
      zf.extract(info, dest_dir)

View on GitHub (pinned to e6e199d060)

Solutions

  1. Run the binary via its bazel-generated location (bazel run / bazel-bin path with the adjacent .runfiles tree intact).
  2. On Windows ensure --enable_runfiles is set (or that the .runfiles manifest is next to the stub) so resolution can succeed.
  3. If you must relocate the binary, move the whole _runfiles directory alongside it and preserve the '*_runfiles' naming.
Defensive patterns

Strategy: validation

Validate before calling

import os, sys
stub = os.path.abspath(sys.argv[0])
rf = stub + '.runfiles'
if not (os.path.isdir(rf) or os.path.exists(stub + '.runfiles_manifest')):
    raise RuntimeError('no runfiles next to %s; run via bazel' % stub)

Prevention

When it happens

Trigger: Executing the generated python stub after its runfiles tree/manifest was deleted or never created — e.g. the binary was copied out of bazel-out without its .runfiles sibling, or runfiles are disabled (Windows without --enable_runfiles) and the manifest is missing.

Common situations: Copying a bazel-built python binary elsewhere and running it standalone; 'bazel clean' removing the runfiles tree while the stub remains; Windows builds where only the manifest mode is available but the manifest was not passed.

Related errors


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