abhigyanpatwari/GitNexus · error · ValueError

oracle parents must be real directories: {relative}

Error message

oracle parents must be real directories: {relative}

What it means

Raised by _read_oracle_file when an intermediate parent directory of an oracle source is a symlink or not a directory (e.g. a regular file). The harness walks every parent component with lstat to ensure the path is composed entirely of real directories, blocking symlink-based traversal and substitution attacks against the oracle store.

Source

Thrown at eval/workflow_bench/oracle_assets.py:137

        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):
            raise ValueError(f"oracle source must be a bounded regular non-symlink file: {relative}")
        descriptor = os.open(path, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0))
    except ValueError:
        raise
    except OSError as exc:
        raise ValueError(f"oracle source is unreadable: {relative}") from exc
    try:
        opened = os.fstat(descriptor)
        if (
            stat.S_ISLNK(before.st_mode)
            or not stat.S_ISREG(before.st_mode)
            or not stat.S_ISREG(opened.st_mode)
            or before.st_dev != opened.st_dev

View on GitHub (pinned to d540b00184)

Solutions

  1. Remove or replace any symlinks in the oracle source path's directory chain with real directories.
  2. Ensure every component except the final file is a genuine directory.
  3. Re-extract the oracle assets from a trusted source to eliminate tampering.
Defensive patterns

Strategy: validation

Validate before calling

import stat
from pathlib import Path

def assert_real_parents(root: Path, relative) -> None:
    cur = root
    for part in Path(relative).parts[:-1]:
        cur /= part
        md = cur.lstat()
        if stat.S_ISLNK(md.st_mode) or not stat.S_ISDIR(md.st_mode):
            raise ValueError(f"{cur} is not a real directory")

Type guard

def parents_all_real_dirs(root, relative) -> bool:
    import stat
    cur = Path(root)
    for part in Path(relative).parts[:-1]:
        cur /= part
        try:
            md = cur.lstat()
        except OSError:
            return False
        if stat.S_ISLNK(md.st_mode) or not stat.S_ISDIR(md.st_mode):
            return False
    return True

Try / catch

try:
    payload = _read_oracle_file(root, relative)
except ValueError as exc:
    if "must be real directories" in str(exc):
        raise SystemExit(f"Symlink/non-dir in oracle path: {relative}") from exc
    raise

Prevention

When it happens

Trigger: An intermediate path component is a symbolic link; an intermediate component is a regular file or special device rather than a directory; the source path traverses through a symlinked directory.

Common situations: A symlink placed inside the oracle tree (intentional convenience or accidental); an oracle path like 'dir.txt/inner' where a non-directory sits mid-path; tampered or hand-edited oracle directory structure.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/913723803b4dc764. Report an issue: GitHub.