abhigyanpatwari/GitNexus · error · SandboxError
Compound Engineering plugin entry is unreadable: {entry.path
Error message
Compound Engineering plugin entry is unreadable: {entry.path}: {exc} What it means
After scandir succeeds, each entry is stat'd with follow_symlinks=False to classify it. OSError on that per-entry stat raises this error, so a file that disappears or becomes inaccessible between scandir and stat is not ignored.
Source
Thrown at eval/workflow_bench/runtime_mounts.py:325
skills = source / "skills"
if not skills.exists():
raise SandboxError(f"Compound Engineering plugin skills directory is missing: {skills}")
def walk(directory: Path, relative_dir: PurePosixPath) -> Iterator[tuple[PurePosixPath, Path]]:
try:
with os.scandir(directory) as scanned:
entries = sorted(scanned, key=lambda entry: entry.name)
except OSError as exc:
raise SandboxError(f"Compound Engineering plugin directory is unreadable: {directory}: {exc}") from exc
for entry in entries:
relative = relative_dir / entry.name
if _is_forbidden_plugin_path(relative):
continue
try:
metadata = entry.stat(follow_symlinks=False)
except OSError as exc:
raise SandboxError(f"Compound Engineering plugin entry is unreadable: {entry.path}: {exc}") from exc
if stat.S_ISLNK(metadata.st_mode):
raise SandboxError(f"Compound Engineering plugin entries must not be symlinks: {entry.path}")
if stat.S_ISDIR(metadata.st_mode):
yield from walk(Path(entry.path), relative)
elif stat.S_ISREG(metadata.st_mode):
yield relative, Path(entry.path)
else:
raise SandboxError(f"Compound Engineering plugin entries must be regular files: {entry.path}")
for name in _ALLOWED_PLUGIN_DIRS:
directory = source / name
if not directory.exists():
continue
try:
metadata = directory.lstat()
except OSError as exc:
raise SandboxError(f"Compound Engineering plugin component is unreadable: {directory}: {exc}") from exc
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):View on GitHub (pinned to d540b00184)
Solutions
- Make the plugin source immutable during snapshot build (stop concurrent writers).
- Grant read on every file: `chmod -R +r <plugin_dir>`.
- Copy the plugin to a stable local directory before pointing --ce-plugin-dir at it.
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def entries_statable(directory: Path) -> bool:
try:
with os.scandir(directory) as it:
for entry in it:
entry.stat(follow_symlinks=False)
except OSError:
return False
return True Try / catch
try:
list(_plugin_files(source))
except SandboxError as exc:
if "entry is unreadable" in str(exc):
# freeze the tree (stop concurrent writers) and re-run
...
raise Prevention
- Freeze the plugin source (no concurrent writes) during the snapshot build.
- Ensure every file is owner-readable by the harness user.
When it happens
Trigger: A file is deleted or has its permissions changed between os.scandir and entry.stat; NFS/lazy-filesystem stat failure; ACL denies stat on a specific entry.
Common situations: Concurrent builds mutating the plugin tree; flaky network filesystem; per-file ACLs applied inconsistently.
Related errors
- Compound Engineering plugin file is unreadable: {path}: {exc
- Compound Engineering plugin directory is unreadable: {direct
- Compound Engineering plugin component is unreadable: {direct
- Could not read ${GITNEXUS_RC_FILENAME}: ${(err as Error).mes
- candidate destination is unreadable: {relative}: {exc}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/9fa22c65ee7cc7e0.
Report an issue: GitHub.