abhigyanpatwari/GitNexus · error · ValueError
oracle root must be a real non-symlink directory: {lexical}
Error message
oracle root must be a real non-symlink directory: {lexical} What it means
Raised by _real_oracle_root when the oracle root exists but is a symlink, is not a directory, or its resolved path differs from its lexical path (i.e. it is reachable through a symlink). The harness requires a real, non-symlink directory to prevent path-traversal and TOCTOU tricks against the oracle store.
Source
Thrown at eval/workflow_bench/oracle_assets.py:124
source = _bounded_relative_path(declaration.get("source"), label=f"task {task_id} oracle source")
target = _bounded_relative_path(declaration.get("target"), label=f"task {task_id} oracle target")
if source.as_posix() in sources:
raise ValueError(f"task {task_id} oracle source is duplicated: {source}")
if target.as_posix() in targets:
raise ValueError(f"task {task_id} oracle target is duplicated: {target}")
sources.add(source.as_posix())
targets.add(target.as_posix())
def _real_oracle_root(root: Path) -> Path:
lexical = root.expanduser().absolute()
try:
metadata = lexical.lstat()
resolved = lexical.resolve(strict=True)
except OSError as exc:
raise ValueError(f"oracle root is unavailable: {lexical}") from exc
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode) or resolved != lexical:
raise ValueError(f"oracle root must be a real non-symlink directory: {lexical}")
return lexical
def _read_oracle_file(root: Path, relative: PurePosixPath) -> bytes:
current = root
for part in relative.parts[:-1]:
current /= part
try:
metadata = current.lstat()
except OSError as exc:
raise ValueError(f"oracle parent is unreadable: {relative}") from exc
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
raise ValueError(f"oracle parents must be real directories: {relative}")
path = root.joinpath(*relative.parts)
try:
before = path.lstat()
if stat.S_ISLNK(before.st_mode) or not stat.S_ISREG(before.st_mode):View on GitHub (pinned to d540b00184)
Solutions
- Point the oracle root at a real directory, not a symlink.
- Replace any symlink in the path chain with the actual directory it resolves to.
- Ensure no parent directory of the oracle root is a symlink; use readlink -f to find the real location and use that.
- Confirm the target is a directory (stat shows S_IFDIR).
Defensive patterns
Strategy: validation
Validate before calling
import stat
from pathlib import Path
def assert_real_dir(path: Path) -> None:
lex = path.expanduser().absolute()
md = lex.lstat()
if stat.S_ISLNK(md.st_mode) or not stat.S_ISDIR(md.st_mode) or lex.resolve(strict=True) != lex:
raise ValueError(f"{lex} must be a real non-symlink directory") Type guard
def is_real_non_symlink_dir(path) -> bool:
import stat
p = Path(path).expanduser().absolute()
try:
md = p.lstat()
except OSError:
return False
return not stat.S_ISLNK(md.st_mode) and stat.S_ISDIR(md.st_mode) and p.resolve(strict=True) == p Try / catch
try:
snap = capture_task_oracle(task, root=root)
except ValueError as exc:
if "must be a real non-symlink directory" in str(exc):
root = root.resolve(strict=True)
snap = capture_task_oracle(task, root=root)
else:
raise Prevention
- Never symlink the oracle root; always use the real directory path.
- Resolve symlinks in the working directory before computing the oracle root path.
- Document the real-directory requirement in benchmark setup instructions.
When it happens
Trigger: oracle root is a symbolic link; it is a regular file rather than a directory; an intermediate component of the path is a symlink causing resolved != lexical.
Common situations: Someone symlinked the oracles directory for convenience; the path points at a file; the working directory is itself under a symlink (e.g. /tmp is a symlink on some macOS setups) making resolve() diverge from the lexical absolute path.
Related errors
- oracle parents must be real directories: {relative}
- oracle source must be a bounded regular non-symlink file: {r
- oracle sanitization requires a self-contained clone: {root}
- oracle sanitization requires a real self-contained clone: {r
- oracle root is unavailable: {lexical}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/2044742198a27959.
Report an issue: GitHub.