abhigyanpatwari/GitNexus · critical · SandboxError

dependency symlink is dangling or escapes its snapshot: {ent

Error message

dependency symlink is dangling or escapes its snapshot: {entry.path}

What it means

Second-stage check in _validate_dependency_symlinks for symlinks that stay inside the sandbox but, when resolved against the on-disk snapshot (container/payload/...), either fail Path.resolve(strict=True) (dangling target) or land outside the snapshot's payload/ boundary.

Source

Thrown at eval/workflow_bench/task_assets.py:690

    for entry in entries:
        if entry.kind != "symlink":
            continue
        target = PurePosixPath(entry.link_target)
        relative_to_payload = entry.path.relative_to(manifest_boundary)
        sandbox_resolved = PurePosixPath(
            posixpath.normpath((sandbox_mount / relative_to_payload.parent / target).as_posix())
        )
        if sandbox_resolved != sandbox_boundary and sandbox_boundary not in sandbox_resolved.parents:
            raise SandboxError(f"dependency symlink escapes the sandbox workspace: {entry.path}")
        manifest_resolved = PurePosixPath(posixpath.normpath((entry.path.parent / target).as_posix()))
        if manifest_resolved != manifest_boundary and manifest_boundary not in manifest_resolved.parents:
            continue
        link = container / Path(*entry.path.parts)
        try:
            resolved = link.resolve(strict=True)
            resolved.relative_to(snapshot_boundary)
        except (OSError, RuntimeError, ValueError) as exc:
            raise SandboxError(f"dependency symlink is dangling or escapes its snapshot: {entry.path}") from exc


def _preflight_exact_root(clone: Path, relative: PurePosixPath) -> None:
    """Reject symlink/special hazards while permitting replaceable type conflicts."""

    flags = os.O_RDONLY | os.O_DIRECTORY | getattr(os, "O_CLOEXEC", 0) | getattr(os, "O_NOFOLLOW", 0)
    current = os.open(clone, flags)
    try:
        for index, part in enumerate(relative.parts):
            try:
                mode = os.stat(part, dir_fd=current, follow_symlinks=False).st_mode
            except FileNotFoundError:
                return
            last = index == len(relative.parts) - 1
            if stat.S_ISLNK(mode):
                role = "target cannot be a symlink" if last else "target has a symlink parent"
                raise SandboxError(f"sandbox_copy {role}: {relative}")
            if last:

View on GitHub (pinned to d540b00184)

Solutions

  1. Include the symlink's target in the same dependency snapshot, or make the link relative to a captured path
  2. Re-capture the dependency from a clean checkout so all link targets are present
  3. Drop the symlink from the declaration if it is unused at runtime
Defensive patterns

Strategy: validation

Validate before calling

import posixpath
from pathlib import Path, PurePosixPath

def dangling_or_escaping(container: Path, entries) -> list[str]:
    boundary = (container / "payload").resolve(strict=True)
    manifest_boundary = PurePosixPath("payload")
    bad = []
    for e in entries:
        if e.get("kind") != "symlink":
            continue
        tgt = PurePosixPath(e["link_target"])
        manifest_resolved = PurePosixPath(posixpath.normpath((PurePosixPath(e["path"]).parent / tgt).as_posix()))
        if manifest_resolved != manifest_boundary and manifest_boundary not in manifest_resolved.parents:
            continue  # checked elsewhere
        link = container / Path(*PurePosixPath(e["path"]).parts)
        try:
            link.resolve(strict=True).relative_to(boundary)
        except (OSError, RuntimeError, ValueError):
            bad.append(e["path"])
    return bad

Try / catch

from eval.workflow_bench.proposer_sandbox import SandboxError

try:
    snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
except SandboxError as exc:
    if "dangling or escapes its snapshot" in str(exc):
        raise SystemExit(f"dependency symlink target missing; re-capture the dependency: {exc}") from exc
    raise

Prevention

When it happens

Trigger: A symlink points at a file not captured in the same dependency snapshot (dangling); a symlink uses a ../../ chain that exits the payload dir into another dependency container or outside the snapshot.

Common situations: Partial capture where the link target was outside the captured subtree; dependency packaging that assumes a sibling directory not present in the snapshot.

Related errors


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