abhigyanpatwari/GitNexus · error · ValueError
oracle stage parent must be a real directory: {item.target}
Error message
oracle stage parent must be a real directory: {item.target} What it means
Inside _write_stage_file (used by staged_task_oracle to materialize oracle files AFTER the model exits): the harness mkdir's the destination parents, then walks each parent with lstat to confirm it is a real, non-symlink directory before writing the oracle file read-only. A symlink/non-dir parent would indicate a TOCTOU swap (an adversarial model process trying to redirect the oracle write outside the stage root).
Source
Thrown at eval/workflow_bench/oracle_assets.py:470
parents = _git_checked(root, ["show", "-s", "--format=%P", "HEAD"], timeout=60)
if parents:
raise ValueError("oracle sanitization snapshot unexpectedly retained parent history")
if _git_checked(root, ["remote"], timeout=60):
raise ValueError("oracle sanitization retained a repository remote")
if logs.exists() or logs.is_symlink():
raise ValueError("oracle sanitization retained reflog metadata")
return sanitized_head
def _write_stage_file(stage_root: Path, item: OracleFileSnapshot) -> None:
destination = stage_root.joinpath(*PurePosixPath(item.target).parts)
destination.parent.mkdir(parents=True, mode=0o700, exist_ok=True)
current = stage_root
for part in PurePosixPath(item.target).parts[:-1]:
current /= part
metadata = current.lstat()
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
raise ValueError(f"oracle stage parent must be a real directory: {item.target}")
current.chmod(0o700)
descriptor = os.open(
destination,
os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0),
0o400,
)
try:
view = memoryview(item.payload)
while view:
written = os.write(descriptor, view)
if written <= 0:
raise OSError("short write while staging oracle")
view = view[written:]
os.fchmod(descriptor, 0o400)
os.fsync(descriptor)
finally:
os.close(descriptor)
View on GitHub (pinned to d540b00184)
Solutions
- Ensure staged_task_oracle's worktree is private to a single task and not writable by the model process.
- Inspect `.wfbench-oracle-*/` lineage for symlinks: `find <worktree>/.wfbench-oracle-* -type l`.
- Validate item.target does not traverse into existing file paths; ensure the stage root is created fresh each run.
Defensive patterns
Strategy: validation
Validate before calling
import stat
from pathlib import Path, PurePosixPath
def stage_parents_are_real(stage_root: Path, target: str) -> bool:
cur = stage_root
for part in PurePosixPath(target).parts[:-1]:
cur = cur / part
try:
st = cur.lstat()
except OSError:
return False
if stat.S_ISLNK(st.st_mode) or not stat.S_ISDIR(st.st_mode):
return False
return True
Type guard
def is_unsafe_stage_parent(exc: BaseException) -> bool:
return isinstance(exc, ValueError) and "stage parent must be a real directory" in str(exc)
Try / catch
from eval.workflow_bench import oracle_assets
try:
with oracle_assets.staged_task_oracle(worktree, snapshot) as root:
run_command(root)
except ValueError as exc:
raise AbortTask(f"oracle staging failed: {exc}") from exc
Prevention
- Give each task a private worktree the model cannot write to until staging is complete.
- Never reuse a .wfbench-oracle-* directory across runs.
When it happens
Trigger: Triggered when, between mkdir(parents, exist_ok=True) and the parent walk, one of the parent components of item.target becomes a symlink or non-directory — e.g., a model-launched process racing to replace a directory with a symlink inside .wfbench-oracle-<hex>/.
Common situations: A model-under-test that escapes its sandbox and races the oracle staging write; a bug in target path construction producing a path that collides with an existing file; concurrent staged_task_oracle calls sharing a root.
Related errors
- benchmark harness checkout must contain only real directorie
- unsafe Git metadata blocks oracle sanitization: {pseudo_ref}
- unsafe Git reflog metadata blocks oracle sanitization
- results artifact parent must be a real directory: {current}
- oracle root must be a real non-symlink directory: {lexical}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/ec61b6720deef3b2.
Report an issue: GitHub.