abhigyanpatwari/GitNexus · error · SandboxError
Compound Engineering plugin directory is unreadable: {direct
Error message
Compound Engineering plugin directory is unreadable: {directory}: {exc} What it means
Inside the recursive walk() over skills/scripts/assets, os.scandir() failure on any directory raises SandboxError with this message. The harness will not silently skip an unreadable subtree.
Source
Thrown at eval/workflow_bench/runtime_mounts.py:317
required_manifest = _ALLOWED_PLUGIN_MANIFESTS[0]
manifest_path = source / Path(*required_manifest.parts)
if not manifest_path.exists():
raise SandboxError(f"Compound Engineering plugin manifest is missing: {manifest_path}")
for relative in _ALLOWED_PLUGIN_MANIFESTS:
candidate = source / Path(*relative.parts)
if candidate.exists():
yield relative, candidate
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:View on GitHub (pinned to d540b00184)
Solutions
- Grant read+execute on the whole tree: `chmod -R +rX <plugin_dir>`.
- Re-extract the plugin from a clean tarball to eliminate ACL drift.
- Ensure no process is modifying the plugin source while the snapshot is being built.
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def plugin_dirs_scannable(source: Path) -> bool:
for name in ("skills", "scripts", "assets"):
d = source / name
if not d.exists():
continue
try:
with os.scandir(d):
pass
except OSError:
return False
return True Try / catch
try:
list(_plugin_files(source))
except SandboxError as exc:
if "directory is unreadable" in str(exc):
# chmod -R +rX the plugin source, or copy to a stable local path
...
raise Prevention
- Run `chmod -R +rX` on the plugin source before benchmarking.
- Copy the plugin to a local readonly directory and point --ce-plugin-dir there.
When it happens
Trigger: Permission denied (EACCES) on a subdirectory under skills/, scripts/, or assets/; I/O error (EIO) on the underlying filesystem; directory removed mid-scan.
Common situations: Restrictive ACLs applied to part of the plugin tree; container with read-only bind mounts that omit execute permission; concurrent modification during snapshot build.
Related errors
- transcript artifact parent must be owner-only: {current}
- required executable is not an executable regular file: {path
- Compound Engineering plugin manifest directory is unavailabl
- Compound Engineering plugin entry is unreadable: {entry.path
- Compound Engineering plugin entries must not be symlinks: {e
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/8e490d0d8f386476.
Report an issue: GitHub.