abhigyanpatwari/GitNexus · error · ValueError
duplicate overlay destination: {target}
Error message
duplicate overlay destination: {target} What it means
Thrown in `_prepare_targets` when two entries in the overlay payload map to the same canonical/shipped target path. `mirror_targets(relative)` is expanded for every `(relative, content)` pair and the set `seen` rejects the second occurrence, so the overlay's own content produces an ambiguous destination.
Source
Thrown at eval/workflow_bench/promotion_apply.py:451
if error in {errno.ENOSYS, errno.EINVAL, errno.EOPNOTSUPP}:
raise RuntimeError("atomic overlay exchange is unavailable on this filesystem")
raise OSError(error, os.strerror(error), f"{left} <-> {right}")
def _prepare_targets(
payload: list[tuple[PurePosixPath, bytes]],
repo_root: Path,
) -> tuple[Path, int, list[dict[str, Any]]]:
"""Resolve and snapshot every canonical/shipped destination exactly once."""
root, root_descriptor = _open_repository_root(repo_root)
prepared: list[dict[str, Any]] = []
seen: set[PurePosixPath] = set()
try:
for relative, content in payload:
for target in mirror_targets(relative):
if target in seen:
raise ValueError(f"duplicate overlay destination: {target}")
seen.add(target)
parent_descriptor = _open_target_parent(root_descriptor, target)
try:
original, mode = _read_destination_at(
parent_descriptor,
target.name,
target=target,
)
except BaseException:
os.close(parent_descriptor)
raise
prepared.append(
{
"target": target,
"destination": root / target,
"parent_path": root / target.parent,
"parent_descriptor": parent_descriptor,
"name": target.name,View on GitHub (pinned to d540b00184)
Solutions
- Inspect the offending target printed in the message and search the overlay payload for entries whose `mirror_targets()` yields it.
- Run `candidate_overlay_payload(overlay)` and print `[t for rel, _ in payload for t in mirror_targets(rel)]` to find duplicates before calling apply.
- Remove the duplicate entry from the overlay, or fix the `mirror_targets` mapping that creates the collision.
- Add a unit test that asserts the deduplicated target set equals the raw target list.
Example fix
# diagnostic from workflow_bench.promotion_apply import candidate_overlay_payload, mirror_targets from collections import Counter _, payload = candidate_overlay_payload(overlay) targets = [str(t) for rel, _ in payload for t in mirror_targets(rel)] print([t for t, c in Counter(targets).items() if c > 1]) # remove these from the overlay
Defensive patterns
Strategy: validation
Validate before calling
from collections import Counter
from pathlib import PurePosixPath
from workflow_bench.promotion_apply import candidate_overlay_payload, mirror_targets
def overlay_targets_are_unique(overlay) -> bool:
_, payload = candidate_overlay_payload(overlay)
targets = [str(t) for rel, _ in payload for t in mirror_targets(rel)]
dupes = [t for t, c in Counter(targets).items() if c > 1]
if dupes:
print("duplicate targets:", dupes)
return False
return True Type guard
null
Try / catch
null
Prevention
- Always call `overlay_targets_are_unique(overlay)` before apply or base-digest capture.
- Treat the overlay manifest as immutable once digests are recorded; rebuild it from a single source of truth.
- Unit-test `mirror_targets` for the paths you ship so no two canonical paths map to the same target.
When it happens
Trigger: The overlay file declares two canonical paths whose `mirror_targets()` expansion collides (e.g. the same path shipped twice, or a path and its mirror alias resolving to the same target). Reproducible by calling `apply_promoted_overlay()` or `destination_base_digests()` with such an overlay.
Common situations: Editing an overlay manifest to add a path without removing its old alias; a `mirror_targets` rule that maps both a path and a sibling to the same target; renaming a file but leaving the old entry; merging two overlays whose targets overlap.
Related errors
- overlay destination escapes repository: {target}
- overlay destination parent is unavailable: {target}
- overlay destination parent must not be a symlink: {target}
- committed promotion base is not an immutable object id
- committed overlay destination is unavailable: {target}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/8ec2a6bba7e4611c.
Report an issue: GitHub.