abhigyanpatwari/GitNexus · critical · SandboxError
sandbox_copy path changed while opening: {relative}
Error message
sandbox_copy path changed while opening: {relative} What it means
_open_child compares (st_dev, st_ino, S_IFMT) from the pre-open stat against the post-open fstat. A mismatch means the directory entry was substituted (rename, or unlink+recreate) during the open window — a classic TOCTOU swap that the containment contract refuses to silently accept.
Source
Thrown at eval/workflow_bench/task_assets.py:658
try:
descriptor = os.open(name, flags, dir_fd=parent_descriptor)
except OSError as exc:
raise SandboxError(f"sandbox_copy path changed or is unreadable: {relative}: {exc}") from exc
opened = os.fstat(descriptor)
if not (stat.S_ISDIR(opened.st_mode) or stat.S_ISREG(opened.st_mode)):
os.close(descriptor)
raise SandboxError(f"sandbox_copy accepts only regular files and directories: {relative}")
if (
opened.st_dev,
opened.st_ino,
stat.S_IFMT(opened.st_mode),
) != (
metadata.st_dev,
metadata.st_ino,
stat.S_IFMT(metadata.st_mode),
):
os.close(descriptor)
raise SandboxError(f"sandbox_copy path changed while opening: {relative}")
return descriptor
def _validate_dependency_symlinks(
container: Path,
entries: tuple[AssetManifestEntry, ...],
*,
mount_target: PurePosixPath,
) -> None:
snapshot_boundary = (container / "payload").resolve(strict=True)
manifest_boundary = PurePosixPath("payload")
sandbox_boundary = PurePosixPath(SANDBOX_WORKSPACE)
sandbox_mount = sandbox_boundary / mount_target
for entry in entries:
if entry.kind != "symlink":
continue
target = PurePosixPath(entry.link_target)
relative_to_payload = entry.path.relative_to(manifest_boundary)View on GitHub (pinned to d540b00184)
Solutions
- Freeze the worktree (read-only bind mount, or a dedicated clone per run)
- Re-run capture after quiescing all writers
- Use one private worktree per concurrent arm so no cross-arm mutation can occur
Defensive patterns
Strategy: try-catch
Try / catch
from eval.workflow_bench.proposer_sandbox import SandboxError
try:
snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
except SandboxError as exc:
if "path changed while opening" in str(exc):
raise SystemExit(f"TOCTOU inode swap during capture; freeze the worktree: {exc}") from exc
raise Prevention
- Freeze the worktree (read-only bind mount) before capture
- Use a dedicated clone per run instead of mutating a shared one
- Stop git checkout/rsync/builds against the worktree during capture
When it happens
Trigger: A component is swapped between stat and open; concurrent git checkout, rsync, or build tooling rewriting the tree during capture.
Common situations: Live worktree edits during benchmarking; a worktree shared across arms without coordination.
Related errors
- transcript artifact changed while opening: {path}
- transcript artifact changed while reading: {path}
- sandbox_copy path changed or is unreadable: {relative}: {exc
- {label} is unreadable: {path}: {exc}
- {label} changed while opening: {path}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/9336375b5864e98b.
Report an issue: GitHub.