abhigyanpatwari/GitNexus · error · OSError

short write while staging candidate overlay

Error message

short write while staging candidate overlay

What it means

Thrown as an OSError inside _replace_regular_file (evolution.py:211) when os.write on the staged temp descriptor returns a value <= 0 while writing overlay content. A blocking local regular-file write should never return 0, so this signals an I/O-level failure: the filesystem is out of space, the device errored, or the descriptor became invalid. The temp file is unlinked (best-effort) and the error propagates.

Source

Thrown at eval/workflow_bench/evolution.py:211

            existing = None
        except OSError as exc:
            raise ValueError(f"candidate destination is unreadable: {relative}: {exc}") from exc
        if existing is not None and (stat.S_ISLNK(existing.st_mode) or not stat.S_ISREG(existing.st_mode)):
            raise ValueError(f"candidate destination must be a regular non-symlink file: {relative}")

        temporary = f".wfbench-overlay-{secrets.token_hex(12)}"
        temp_descriptor = os.open(
            temporary,
            os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0),
            0o600,
            dir_fd=descriptor,
        )
        try:
            view = memoryview(content)
            while view:
                written = os.write(temp_descriptor, view)
                if written <= 0:
                    raise OSError("short write while staging candidate overlay")
                view = view[written:]
            os.fchmod(temp_descriptor, 0o644)
        except BaseException:
            try:
                os.unlink(temporary, dir_fd=descriptor)
            except OSError:
                pass
            raise
        finally:
            os.close(temp_descriptor)
        try:
            os.replace(
                temporary,
                leaf,
                src_dir_fd=descriptor,
                dst_dir_fd=descriptor,
            )
        except BaseException:

View on GitHub (pinned to d540b00184)

Solutions

  1. Free disk space on the filesystem holding the clone/worktree and retry.
  2. Move the worktree to a healthy local filesystem (not a network mount) and re-run.
  3. Catch OSError around apply_candidate_overlay, clean up partial state, and retry once.

Example fix

# before: single attempt, surfaces OSError on full disk
apply_candidate_overlay(overlay, worktree, sandbox=sandbox)

# after: retry once after ensuring space
import shutil
for attempt in range(2):
    try:
        return apply_candidate_overlay(overlay, worktree, sandbox=sandbox)
    except OSError as exc:
        if 'short write' not in str(exc) or attempt:
            raise
        shutil.disk_usage(worktree)  # inspect; free space externally before retry
Defensive patterns

Strategy: retry

Validate before calling

import shutil
from pathlib import Path

def has_disk_space(path: Path, need_bytes: int) -> bool:
    usage = shutil.disk_usage(path)
    return usage.free >= need_bytes

Type guard

null

Try / catch

try:
    apply_candidate_overlay(overlay, worktree, sandbox=sandbox)
except OSError as exc:
    if 'short write' in str(exc):
        # free space / move worktree to local disk, then retry once
        ...

Prevention

When it happens

Trigger: Disk full while staging the overlay temp file; an I/O error on the underlying device; the temp descriptor was closed/invalidated under the writer (signal, FS disconnect).

Common situations: CI runner or sandbox tmpfs out of space; a full disk on the host holding the clone; a flaky network/cloud filesystem under the worktree.

Related errors


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