abhigyanpatwari/GitNexus · error · SandboxError

evidence destination already exists: {destination}

Error message

evidence destination already exists: {destination}

What it means

Raised by stage_evidence_bundle when the destination directory already exists (destination.resolve().exists() is true). The writer wants to mkdir(parents=True, mode=0o700) into a fresh path and treats a pre-existing destination as a collision it must not silently overwrite, since clobbering could mix old unredacted bytes with new evidence.

Source

Thrown at eval/workflow_bench/proposer_sandbox.py:222

        raw = value
    elif isinstance(value, str):
        raw = value.encode()
    else:
        raw = (json.dumps(value, sort_keys=True, separators=(",", ":")) + "\n").encode()
    return redact_text(raw.decode(errors="replace"), secrets).encode()


def stage_evidence_bundle(
    destination: Path,
    entries: Mapping[str, Any],
    *,
    secrets: Sequence[str] = (),
) -> Path:
    """Write a redacted owner-only evidence bundle with hard byte caps."""

    destination = destination.resolve()
    if destination.exists():
        raise SandboxError(f"evidence destination already exists: {destination}")
    destination.mkdir(parents=True, mode=0o700)
    destination.chmod(0o700)
    total = 0
    try:
        for name, value in entries.items():
            relative = PurePosixPath(name)
            if len(relative.parts) != 1 or relative.name in {"", ".", ".."}:
                raise SandboxError(f"evidence names must be simple relative files: {name!r}")
            payload = _evidence_bytes(value, secrets)
            if len(payload) > MAX_EVIDENCE_FILE_BYTES:
                raise SandboxError(f"evidence exceeds the per-file limit: {name}")
            total += len(payload)
            if total > MAX_BUNDLE_BYTES:
                raise SandboxError("evidence bundle exceeds the total byte limit")
            path = destination / relative.name
            path.write_bytes(payload)
            path.chmod(0o600)
    except BaseException:

View on GitHub (pinned to d540b00184)

Solutions

  1. Pass a fresh per-run destination: append a unique suffix (uuid, timestamp, pid) or use tempfile.mkdtemp as the parent and a new leaf name.
  2. Delete the existing destination before staging if you are sure it is stale: shutil.rmtree(destination, ignore_errors=True) then retry.
  3. On retry, generate a new destination under the session private_root rather than reusing the literal same path.
  4. Ensure the orchestrator cleans the staging root at session end so retries start clean.

Example fix

// before
dest = Path("/tmp/wfbench/task-7/evidence")  # exists from prior crash
stage_evidence_bundle(dest, entries)
// after
dest = Path(tempfile.mkdtemp(prefix="evidence-")) / "evidence"
stage_evidence_bundle(dest, entries)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import tempfile, uuid

def fresh_destination(base: Path) -> Path:
    return base / f'evidence-{uuid.uuid4().hex}' if base.exists() else base

dest = fresh_destination(Path(tempfile.mkdtemp(prefix='wfbench-'))) / 'bundle'

Type guard

null

Try / catch

try:
    stage_evidence_bundle(dest, entries, secrets=secrets)
except SandboxError as exc:
    if 'already exists' in str(exc):
        import shutil
        shutil.rmtree(dest, ignore_errors=True)
        stage_evidence_bundle(dest, entries, secrets=secrets)
    raise

Prevention

When it happens

Trigger: Calling stage_evidence_bundle with a destination Path that already exists on disk (file or directory), including a leftover bundle from a previous run or retry.

Common situations: A retry reuses the same destination path after a prior run crashed mid-stage; the destination sits under a temp base whose name is deterministic per task and the prior artifact was not cleaned; two concurrent tasks share a staging root without per-run names; a SIGKILL beat the failure-path rmtree.

Related errors


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