abhigyanpatwari/GitNexus · error · ValueError

oracle source changed while being captured: {relative}

Error message

oracle source changed while being captured: {relative}

What it means

Raised by _read_oracle_file after reading the full payload, when either the payload length exceeds MAX_ORACLE_FILE_BYTES (512 KiB) or any of the stable stat fields (st_dev, st_ino, st_mode, st_size, st_mtime_ns, st_ctime_ns) changed between the pre-read fstat and a post-read fstat. This detects files mutated, truncated, or replaced while the harness was reading them, ensuring the captured digest is of a fixed, immutable byte sequence.

Source

Thrown at eval/workflow_bench/oracle_assets.py:174

            or before.st_ino != opened.st_ino
            or opened.st_size > MAX_ORACLE_FILE_BYTES
        ):
            raise ValueError(f"oracle source must be a bounded regular non-symlink file: {relative}")
        chunks: list[bytes] = []
        remaining = MAX_ORACLE_FILE_BYTES + 1
        while remaining > 0:
            chunk = os.read(descriptor, min(64 * 1024, remaining))
            if not chunk:
                break
            chunks.append(chunk)
            remaining -= len(chunk)
        payload = b"".join(chunks)
        after = os.fstat(descriptor)
        stable_fields = ("st_dev", "st_ino", "st_mode", "st_size", "st_mtime_ns", "st_ctime_ns")
        if len(payload) > MAX_ORACLE_FILE_BYTES or any(
            getattr(opened, field) != getattr(after, field) for field in stable_fields
        ):
            raise ValueError(f"oracle source changed while being captured: {relative}")
        return payload
    finally:
        os.close(descriptor)


def capture_task_oracle(task: dict[str, Any], *, root: Path = ORACLE_ROOT) -> TaskOracleSnapshot:
    """Capture and digest one task's hidden oracle before a model session."""

    validate_oracle_declaration(task)
    oracle_root = _real_oracle_root(root)
    oracle = task["oracle"]
    command = str(oracle["command"])
    snapshots: list[OracleFileSnapshot] = []
    total = 0
    for declaration in oracle["files"]:
        source = _bounded_relative_path(declaration["source"], label="oracle source")
        target = _bounded_relative_path(declaration["target"], label="oracle target").as_posix()
        payload = _read_oracle_file(oracle_root, source)

View on GitHub (pinned to d540b00184)

Solutions

  1. Freeze oracle assets before capture: copy them to a read-only location and capture from there.
  2. Stop any process that writes to the oracle tree during the benchmark run.
  3. Ensure the file size is stable and below 512 KiB at capture time.
Defensive patterns

Strategy: validation

Validate before calling

import os, stat
from pathlib import Path

def assert_file_stable(root: Path, relative) -> None:
    p = root.joinpath(*Path(relative).parts)
    fd = os.open(p, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0))
    try:
        a = os.fstat(fd)
        os.read(fd, a.st_size)  # touch
        b = os.fstat(fd)
        for f in ("st_dev", "st_ino", "st_mode", "st_size", "st_mtime_ns", "st_ctime_ns"):
            if getattr(a, f) != getattr(b, f):
                raise ValueError(f"{relative} is being modified during read")
    finally:
        os.close(fd)

Type guard

def file_is_quiescent(root, relative) -> bool:
    import os
    p = Path(root).joinpath(*Path(relative).parts)
    try:
        fd = os.open(p, os.O_RDONLY)
    except OSError:
        return False
    try:
        return os.fstat(fd).st_size == p.stat().st_size
    finally:
        os.close(fd)

Try / catch

try:
    payload = _read_oracle_file(root, relative)
except ValueError as exc:
    if "changed while being captured" in str(exc):
        # freeze and retry once from a read-only copy
        raise SystemExit(f"Oracle file {relative} mutated mid-capture; freeze the asset tree") from exc
    raise

Prevention

When it happens

Trigger: A file grows beyond 512 KiB while being read; the file is written, touched, or replaced during the read loop; mtime/ctime changes because another process writes to it mid-capture.

Common situations: Log files or generated outputs being actively written when the oracle is captured; concurrent benchmark tooling touching oracle assets; an editor auto-saving over the file; clock/mtime updates from a filesystem sync.

Related errors


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