abhigyanpatwari/GitNexus · error · SandboxError
sandbox_copy paths collide at {entry.path}
Error message
sandbox_copy paths collide at {entry.path} What it means
Raised by _SnapshotBuilder._record when a manifest entry at a given path was already recorded with different fields (different kind, size, sha256, mode, or link_target). The second recording is rejected because the manifest must be deterministic — the same path cannot have two distinct captured identities in one snapshot. Identical re-recording is a no-op (the early `existing != entry` check returns).
Source
Thrown at eval/workflow_bench/task_assets.py:520
def _ensure_parents(self, relative: PurePosixPath) -> None:
current = PurePosixPath()
for part in relative.parts:
current /= part
existing = self.entries.get(current)
if existing is not None:
if existing.kind != "directory":
raise SandboxError(f"sandbox_copy paths collide at {current}")
continue
self._record(AssetManifestEntry(path=current, kind="directory"))
(self.destination / Path(*current.parts)).mkdir(mode=0o700, exist_ok=True)
def _record(self, entry: AssetManifestEntry) -> None:
_validate_manifest_path(entry.path)
existing = self.entries.get(entry.path)
if existing is not None:
if existing != entry:
raise SandboxError(f"sandbox_copy paths collide at {entry.path}")
return
if self.budget.entries >= MAX_TASK_ASSET_ENTRIES:
raise SandboxError("sandbox_copy exceeds the entry limit")
self.entries[entry.path] = entry
self.budget.entries += 1
def ensure_directory(self, relative: PurePosixPath) -> None:
"""Record and create one extra directory inside this snapshot.
Used for harness-owned mount points that must exist in the captured
bytes rather than be created against a read-only bind at runtime.
"""
self._record_directory(relative)
def finished_entries(self) -> tuple[AssetManifestEntry, ...]:
return tuple(sorted(self.entries.values(), key=lambda entry: entry.path.as_posix()))
View on GitHub (pinned to d540b00184)
Solutions
- Review all sandbox_copy and sandbox_dependencies entries for paths that resolve to the same in-snapshot location; eliminate aliases.
- Quiesce the source tree so a file visited twice yields identical sha256 (stop concurrent writers).
- Ensure each dependency's source maps to a distinct snapshot_path (the harness uses indexed containers, so collision implies duplicate target declarations).
- Run detect_changes or a tree diff to confirm the source is stable across the capture window.
Example fix
// before — two deps target the same in-clone path with different sources
{"sandbox_dependencies": [
{"source": "a/node_modules", "target": "node_modules"},
{"source": "b/node_modules", "target": "node_modules"}
]}
// after — distinct targets
{"sandbox_dependencies": [
{"source": "a/node_modules", "target": "node_modules"}
]} Defensive patterns
Strategy: validation
Validate before calling
from pathlib import PurePosixPath
def validate_distinct_in_snapshot_paths(copy_paths: list[PurePosixPath], dep_targets: list[PurePosixPath]) -> None:
"""Ensure no copy path aliases a dependency target and all targets are distinct."""
seen = {}
for p in list(copy_paths) + list(dep_targets):
if p in seen:
raise ValueError(f"duplicate in-snapshot path: {p}")
seen[p] = True
validate_distinct_in_snapshot_paths(
[PurePosixPath(p) for p in task["sandbox_copy"]],
[PurePosixPath(d["target"]) for d in task.get("sandbox_dependencies", [])],
) Try / catch
from eval.workflow_bench.propposer_sandbox import SandboxError
try:
snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
except SandboxError as exc:
if "paths collide" in str(exc):
# two declarations resolve to the same in-snapshot path with different content
raise
raise Prevention
- Ensure each sandbox_dependency target is distinct and does not alias a sandbox_copy path.
- Quiesce the tree so a file visited twice yields identical sha256.
- Avoid declaring the same source under two dependency targets.
When it happens
Trigger: The same relative path is captured twice with differing metadata within one prepare() call. This can happen if a file is mutated between two traversals (so its sha256 differs), or if the path is reached via two different declaration roots whose trees overlap in a way the declaration-overlap check did not block (e.g. a dependency payload path colliding with a sandbox_copy path).
Common situations: Two sandbox_dependency sources that both contain a `payload/foo` resolved to the same snapshot path but with different contents. A concurrent mutation that changes a file's sha256 between the first and second time the builder visits it. A misconfigured declaration where sandbox_copy and a dependency target alias the same in-snapshot path.
Related errors
- sandbox_copy paths collide at {current}
- Compound Engineering plugin manifest is invalid: {exc}
- CE comparator requires the compound-engineering plugin manif
- Compound Engineering plugin version mismatch: expected {conf
- Compound Engineering plugin is missing required skill: {skil
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/6815d690122f05c0.
Report an issue: GitHub.