abhigyanpatwari/GitNexus · critical · SandboxError
task asset reflink produced an invalid file: {entry.path}
Error message
task asset reflink produced an invalid file: {entry.path} What it means
After _try_reflink reports success, _materialize_file checks that the destination's size equals entry.size. A mismatch implies the reflink produced partial or wrong content — a filesystem bug, concurrent truncation of the source between the pre-open lstat and the ioctl, or a stale manifest size.
Source
Thrown at eval/workflow_bench/task_assets.py:824
) -> int:
metadata = source.lstat()
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISREG(metadata.st_mode) or metadata.st_size != entry.size:
raise SandboxError(f"task asset snapshot file changed: {entry.path}")
temporary = destination.with_name(f".{destination.name}.{uuid.uuid4().hex}.tmp")
source_descriptor = os.open(source, os.O_RDONLY | getattr(os, "O_CLOEXEC", 0) | getattr(os, "O_NOFOLLOW", 0))
destination_descriptor = os.open(
temporary,
os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_CLOEXEC", 0),
0o600,
)
fallback_bytes = 0
try:
opened = os.fstat(source_descriptor)
if _mutation_identity(opened) != _mutation_identity(metadata):
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)View on GitHub (pinned to d540b00184)
Solutions
- Re-prepare the snapshot so the manifest matches the on-disk file
- Check filesystem health (`btrfs scrub start`, `xfs_repair -n`)
- Eliminate concurrent truncaters; if unavoidable, place the cache on a non-clone filesystem so the buffered fallback runs with its own size check
Defensive patterns
Strategy: try-catch
Try / catch
from eval.workflow_bench.proposer_sandbox import SandboxError
try:
snapshot.materialize(clone)
except SandboxError as exc:
if "reflink produced an invalid file" in str(exc):
raise SystemExit(f"reflink integrity failure; re-prepare and check fs health: {exc}") from exc
raise Prevention
- Re-prepare the snapshot so the manifest size matches the on-disk file
- Run filesystem health checks (`btrfs scrub start`, `xfs_repair -n`) on the cache volume
- Eliminate concurrent truncaters of the snapshot files
When it happens
Trigger: The source was truncated between the lstat (which sized the manifest) and the FICLONE ioctl; the filesystem reported success but the clone is partial; manifest size was recorded against a different inode.
Common situations: Concurrent truncation of the snapshot; btrfs/xfs returning a partial clone under space pressure; manifest captured against a since-replaced file.
Related errors
- sandbox_copy file changed while snapshotting: {relative}
- task asset filesystem cannot reflink the snapshot and the bu
- candidate destination parent must be a real directory: {rela
- evidence source must be a regular non-symlink file: {path}
- results directory is unavailable: {root}: {exc}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/50cc479481843d5e.
Report an issue: GitHub.