{"record":{"id":"bb5d9baadc43e6e0","repo":"abhigyanpatwari/GitNexus","slug":"short-write-while-copying-task-assets","errorCode":null,"errorMessage":"short write while copying task assets","messagePattern":"short write while copying task assets","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/task_assets.py","lineNumber":873,"sourceCode":"    try:\n        fcntl.ioctl(destination_descriptor, FICLONE, source_descriptor)\n        return True\n    except OSError as exc:\n        if exc.errno in _REFLINK_UNAVAILABLE:\n            return False\n        raise\n\n\ndef _read_source_chunk(descriptor: int, size: int) -> bytes:\n    return os.read(descriptor, size)\n\n\ndef _write_all(descriptor: int, data: bytes) -> None:\n    view = memoryview(data)\n    while view:\n        written = os.write(descriptor, view)\n        if written <= 0:\n            raise OSError(\"short write while copying task assets\")\n        view = view[written:]\n\n\ndef _mutation_identity(metadata: os.stat_result) -> tuple[int, int, int, int, int, int]:\n    return (\n        metadata.st_dev,\n        metadata.st_ino,\n        metadata.st_mode,\n        metadata.st_size,\n        metadata.st_mtime_ns,\n        metadata.st_ctime_ns,\n    )\n\n\ndef _validate_manifest_path(relative: PurePosixPath) -> None:\n    try:\n        path_bytes = len(relative.as_posix().encode(\"utf-8\"))\n    except UnicodeEncodeError as exc:","sourceCodeStart":855,"sourceCodeEnd":891,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/task_assets.py#L855-L891","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before: clone on a 1 GiB tmpfs with a 428 MiB index and no reflink\nclone = Path('/tmp/clone')   # tmpfs fills up -> short write\n\n# after: clone on a real volume with headroom, ideally reflink-capable\nclone = Path('/var/cache/wfbench/clones/arm1')  # btrfs/xfs, plenty of free space","handlingStrategy":"validation","validationCode":"import shutil\n\ndef assert_clone_writable(clone: Path, min_free_bytes: int) -> None:\n    usage = shutil.disk_usage(clone if clone.exists() else clone.parent)\n    if usage.free < min_free_bytes:\n        raise RuntimeError(\n            f'clone volume has {usage.free} bytes free; need >= {min_free_bytes} '\n            f'for buffered asset copy (reflink may be unavailable)'\n        )\n\n# Call before stage_task_assets with min_free_bytes >= largest sandbox_copy asset\n# (shipped index ~428 MiB) times the number of arms on this volume.","typeGuard":null,"tryCatchPattern":"try:\n    stage_task_assets(task, repo=repo, clone=clone, snapshot=snapshot)\nexcept OSError as exc:\n    if exc.args and 'short write while copying task assets' in str(exc.args[0]):\n        # Destination volume is out of space / unwritable. Free space then retry once;\n        # do NOT loop — fix the underlying capacity issue first.\n        raise RuntimeError('clone volume out of space during asset copy') from exc\n    raise","preventionTips":["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."],"tags":["filesystem","io","disk-full","sandbox"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}