abhigyanpatwari/GitNexus · error · OSError
short write while copying task assets
Error message
short write while copying task assets
What it means
Raised by _write_all when os.write returns a value <= 0, i.e. the destination descriptor refused the chunk. It is a plain OSError (not SandboxError) because the failure is an OS-level I/O condition on the temporary destination file, not a sandbox policy violation.
Source
Thrown at eval/workflow_bench/task_assets.py:873
try:
fcntl.ioctl(destination_descriptor, FICLONE, source_descriptor)
return True
except OSError as exc:
if exc.errno in _REFLINK_UNAVAILABLE:
return False
raise
def _read_source_chunk(descriptor: int, size: int) -> bytes:
return os.read(descriptor, size)
def _write_all(descriptor: int, data: bytes) -> None:
view = memoryview(data)
while view:
written = os.write(descriptor, view)
if written <= 0:
raise OSError("short write while copying task assets")
view = view[written:]
def _mutation_identity(metadata: os.stat_result) -> tuple[int, int, int, int, int, int]:
return (
metadata.st_dev,
metadata.st_ino,
metadata.st_mode,
metadata.st_size,
metadata.st_mtime_ns,
metadata.st_ctime_ns,
)
def _validate_manifest_path(relative: PurePosixPath) -> None:
try:
path_bytes = len(relative.as_posix().encode("utf-8"))
except UnicodeEncodeError as exc:View on GitHub (pinned to d540b00184)
Solutions
- Free space on the destination volume (clone filesystem) and rerun stage_task_assets; the temp file is cleaned up by the os.replace error path.
- Raise MAX_BUFFERED_FALLBACK_BYTES only if reflink is genuinely unavailable AND you have confirmed free space exceeds the asset size; otherwise prefer making reflink work.
- Ensure the clone target lives on a filesystem with enough free space for the largest sandbox_copy asset (the shipped index is ~290-428 MiB) times the number of concurrent arms.
- Verify the destination is not mounted read-only or quota-limited (check df -h and quota -v for the clone path).
Example fix
# before: clone on a 1 GiB tmpfs with a 428 MiB index and no reflink
clone = Path('/tmp/clone') # tmpfs fills up -> short write
# after: clone on a real volume with headroom, ideally reflink-capable
clone = Path('/var/cache/wfbench/clones/arm1') # btrfs/xfs, plenty of free space Defensive patterns
Strategy: validation
Validate before calling
import shutil
def assert_clone_writable(clone: Path, min_free_bytes: int) -> None:
usage = shutil.disk_usage(clone if clone.exists() else clone.parent)
if usage.free < min_free_bytes:
raise RuntimeError(
f'clone volume has {usage.free} bytes free; need >= {min_free_bytes} '
f'for buffered asset copy (reflink may be unavailable)'
)
# Call before stage_task_assets with min_free_bytes >= largest sandbox_copy asset
# (shipped index ~428 MiB) times the number of arms on this volume. Try / catch
try:
stage_task_assets(task, repo=repo, clone=clone, snapshot=snapshot)
except OSError as exc:
if exc.args and 'short write while copying task assets' in str(exc.args[0]):
# Destination volume is out of space / unwritable. Free space then retry once;
# do NOT loop — fix the underlying capacity issue first.
raise RuntimeError('clone volume out of space during asset copy') from exc
raise Prevention
- Check shutil.disk_usage(clone) before staging; budget for the largest asset when reflink is unavailable.
- Prefer reflink-capable filesystems (btrfs/xfs) for the clone target so the buffered fallback rarely runs.
- Size the clone volume for the asset count times arms, not just one copy.
- Do not place clones on read-only or quota-limited mounts.
When it happens
Trigger: Buffered fallback copy (reflink failed with EXDEV/EINVAL/ENOTTY/EOPNOTSUPP/ENOSYS) writing into the .<name>.<uuid>.tmp file in the clone, and os.write returns <= 0. Typical causes: ENOSPC (disk/quota full), EIO (failing drive), EDQUOT, EPIPE, or the temp filesystem being read-only/remounted.
Common situations: CI runner disk full after materializing a ~290 MiB index multiple times; small tmpfs /tmp quota exhausted; Docker devcontainer with a tiny writable layer; reflink unsupported so every arm pays the full buffered copy and the destination volume fills up.
Related errors
- short write while staging candidate overlay
- short write while neutralizing {name}
- cannot scan sanitized graph source: {directory}: {exc}
- GraphEmitSink: ${errors.length} streamed CSV writer(s) hit a
- candidate destination parent must be a real directory: {rela
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/bb5d9baadc43e6e0.
Report an issue: GitHub.