abhigyanpatwari/GitNexus · critical · SandboxError

task asset snapshot file changed while materializing: {entry

Error message

task asset snapshot file changed while materializing: {entry.path}

What it means

Two end-of-copy checks in _materialize_file: (a) after a buffered copy, the total bytes read (fallback_bytes) must equal entry.size; (b) for both reflink and buffered paths, a final _mutation_identity comparison on the source descriptor must equal the post-open identity. Either failing raises this error — the source moved during the copy.

Source

Thrown at eval/workflow_bench/task_assets.py:839

            raise SandboxError(f"task asset snapshot file changed: {entry.path}")
        if _try_reflink(source_descriptor, destination_descriptor):
            if os.fstat(destination_descriptor).st_size != entry.size:
                raise SandboxError(f"task asset reflink produced an invalid file: {entry.path}")
        else:
            if entry.size > fallback_budget:
                raise SandboxError(
                    "task asset filesystem cannot reflink the snapshot and the buffered fallback limit would be exceeded"
                )
            os.ftruncate(destination_descriptor, 0)
            os.lseek(source_descriptor, 0, os.SEEK_SET)
            while True:
                chunk = os.read(source_descriptor, COPY_CHUNK_BYTES)
                if not chunk:
                    break
                _write_all(destination_descriptor, chunk)
                fallback_bytes += len(chunk)
            if fallback_bytes != entry.size:
                raise SandboxError(f"task asset snapshot file changed while materializing: {entry.path}")
        if _mutation_identity(opened) != _mutation_identity(os.fstat(source_descriptor)):
            raise SandboxError(f"task asset snapshot file changed while materializing: {entry.path}")
        os.fchmod(destination_descriptor, 0o600)
    finally:
        os.close(destination_descriptor)
        os.close(source_descriptor)
    try:
        os.replace(temporary, destination)
    except BaseException:
        temporary.unlink(missing_ok=True)
        raise
    return fallback_bytes


def _try_reflink(source_descriptor: int, destination_descriptor: int) -> bool:
    try:
        fcntl.ioctl(destination_descriptor, FICLONE, source_descriptor)
        return True

View on GitHub (pinned to d540b00184)

Solutions

  1. Quiesce all writers to the snapshot during the entire materialize call
  2. Move the snapshot to a local, stable filesystem
  3. Re-prepare the snapshot from a clean capture
Defensive patterns

Strategy: try-catch

Try / catch

from eval.workflow_bench.proposer_sandbox import SandboxError

try:
    snapshot.materialize(clone)
except SandboxError as exc:
    if "changed while materializing" in str(exc):
        raise SystemExit(f"snapshot mutated mid-copy; isolate the cache dir: {exc}") from exc
    raise

Prevention

When it happens

Trigger: The source file was truncated, extended, or replaced mid-copy; a concurrent reader/writer caused the read loop to hit EOF early or read past the expected length.

Common situations: Concurrent truncation of the snapshot; AV scanner rewriting the file mid-copy; network filesystem (9p/NFS) reporting inconsistent sizes.

Related errors


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