abhigyanpatwari/GitNexus · error · SandboxError
required executable is not an executable regular file: {path
Error message
required executable is not an executable regular file: {path} What it means
Raised by _resolve_executable after locating the candidate path: Path(raw).resolve() either is not a regular file or os.access(path, X_OK) is false. The sandbox will not exec something that is a directory, a broken symlink, a non-executable file, or a file the current user cannot execute.
Source
Thrown at eval/workflow_bench/proposer_sandbox.py:470
evidence-provenance.mjs's PATH-scan correctly refuses to trust. This
wrapper is freshly created by the same host process that owns
home/temp/shell-prefix, so it maps to the sandbox's own trusted uid
instead, and simply execs the real interpreter through to do the work.
"""
wrapper = private_root / "python3"
wrapper.write_text('#!/bin/bash\nset -eu\nexec /usr/bin/python3 "$@"\n')
wrapper.chmod(0o500)
return wrapper
def _resolve_executable(executable: Path | str | None, default: str) -> Path:
raw = os.fspath(executable) if executable is not None else shutil.which(default)
if not raw:
raise SandboxError(f"required executable is unavailable: {default}")
path = Path(raw).expanduser().resolve()
if not path.is_file() or not os.access(path, os.X_OK):
raise SandboxError(f"required executable is not an executable regular file: {path}")
return path
def preflight_bubblewrap(bwrap_bin: Path | str | None = None) -> Path:
"""Prove the required namespaces work; never fall back to host execution."""
if sys.platform != "linux":
raise SandboxError(f"Bubblewrap containment is supported only on Linux/WSL2, not {sys.platform}")
bwrap = _resolve_executable(bwrap_bin, "bwrap")
command = [
str(bwrap),
"--unshare-user",
"--unshare-pid",
"--unshare-ipc",
"--unshare-uts",
"--die-with-parent",
"--new-session",
*_runtime_mount_args(),View on GitHub (pinned to d540b00184)
Solutions
- chmod +x the target file if it should be executable.
- Point at the real binary, not a directory or shim: pass the absolute path to the executable file.
- Reinstall the tool if its binary was removed/corrupted.
- Check permissions: ls -l path and ensure an x bit for the current user; fix mount options if noexec.
Example fix
// before
node = _resolve_executable('/opt/claude/nodejs', 'node') # a directory
// after
node = _resolve_executable('/opt/claude/nodejs/bin/node', 'node')
Path(node).chmod(0o755) Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def is_executable_file(p: Path) -> bool:
return p.is_file() and os.access(p, os.X_OK)
exe = Path(shutil.which('node'))
assert is_executable_file(exe)
_resolve_executable(str(exe), 'node') Type guard
import os
from pathlib import Path
def is_executable_regular_file(value: object) -> bool:
if not isinstance(value, Path):
return False
return value.is_file() and os.access(value, os.X_OK) Try / catch
try:
path = _resolve_executable(candidate, 'node')
except SandboxError as exc:
if 'not an executable regular file' in str(exc):
path.chmod(0o755)
path = _resolve_executable(candidate, 'node')
raise Prevention
- chmod +x scripts at install time.
- Pass absolute paths to real binaries, not directories or shims.
- Check is_file()+os.access(X_OK) before calling.
- Watch for noexec mounts in CI.
When it happens
Trigger: An explicit executable argument (or a which() result) points to a directory, a file without the executable bit, a symlink whose target is missing/non-executable, or a path the current user cannot execute.
Common situations: Wrapper script created without chmod +x; path points at a directory (e.g. /opt/claude/nodejs instead of the node binary); filesystem mounted noexec; broken symlink returned by a stale which cache; running as a user without execute rights on the binary (permissions 0o644); a pyenv/asdf shim that lost its target after an uninstall.
Related errors
- transcript artifact parent must be owner-only: {current}
- Compound Engineering plugin directory is unreadable: {direct
- sandbox_copy directory is unreadable: {relative}: {exc}
- Could not read ${GITNEXUS_RC_FILENAME}: ${(err as Error).mes
- candidate destination parent must be a real directory: {rela
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/1d1eb09e35f19870.
Report an issue: GitHub.