{"record":{"id":"bd9dbe74eb2a87f7","repo":"abhigyanpatwari/GitNexus","slug":"sandbox-copy-role-relative","errorCode":null,"errorMessage":"sandbox_copy {role}: {relative}","messagePattern":"sandbox_copy (.+?): (.+?)","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"critical","filePath":"eval/workflow_bench/task_assets.py","lineNumber":707,"sourceCode":"        except (OSError, RuntimeError, ValueError) as exc:\n            raise SandboxError(f\"dependency symlink is dangling or escapes its snapshot: {entry.path}\") from exc\n\n\ndef _preflight_exact_root(clone: Path, relative: PurePosixPath) -> None:\n    \"\"\"Reject symlink/special hazards while permitting replaceable type conflicts.\"\"\"\n\n    flags = os.O_RDONLY | os.O_DIRECTORY | getattr(os, \"O_CLOEXEC\", 0) | getattr(os, \"O_NOFOLLOW\", 0)\n    current = os.open(clone, flags)\n    try:\n        for index, part in enumerate(relative.parts):\n            try:\n                mode = os.stat(part, dir_fd=current, follow_symlinks=False).st_mode\n            except FileNotFoundError:\n                return\n            last = index == len(relative.parts) - 1\n            if stat.S_ISLNK(mode):\n                role = \"target cannot be a symlink\" if last else \"target has a symlink parent\"\n                raise SandboxError(f\"sandbox_copy {role}: {relative}\")\n            if last:\n                if not (stat.S_ISDIR(mode) or stat.S_ISREG(mode)):\n                    raise SandboxError(f\"sandbox_copy target has an unsupported type: {relative}\")\n                return\n            if stat.S_ISREG(mode):\n                return\n            if not stat.S_ISDIR(mode):\n                raise SandboxError(f\"sandbox_copy target parent has an unsupported type: {relative}\")\n            next_descriptor = os.open(part, flags, dir_fd=current)\n            os.close(current)\n            current = next_descriptor\n    finally:\n        os.close(current)\n\n\ndef _open_publish_parent(clone: Path, parent: PurePosixPath) -> int:\n    flags = os.O_RDONLY | os.O_DIRECTORY | getattr(os, \"O_CLOEXEC\", 0) | getattr(os, \"O_NOFOLLOW\", 0)\n    current = os.open(clone, flags)","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/task_assets.py#L689-L725","documentation":"_preflight_exact_root walks the destination clone along a declared root and refuses if any component is a symlink. {role} is 'target cannot be a symlink' for the final component or 'target has a symlink parent' for an intermediate one. This protects the publish step from replacing — or being redirected by — a symlink already present in the clone.","triggerScenarios":"A pre-existing symlink in the clone at a declared sandbox_copy root path; a prior arm left a symlink where the snapshot expects to publish a real directory or file.","commonSituations":"A clone reused across runs accumulates symlinks; the repo itself contains symlinks at the declared root paths that the snapshot intends to overwrite.","solutions":["Use a fresh clone per run, or reset it (`git -C <clone> checkout -f && git -C <clone> clean -fdx`) before materializing","Remove the conflicting symlink at the reported path manually","Avoid declaring roots that intentionally collide with symlinks"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os, stat\nfrom pathlib import Path\n\ndef clone_root_is_clean(clone: Path, declarations: list[str]) -> list[str]:\n    bad = []\n    for decl in declarations:\n        parts = Path(decl).parts\n        walker = clone\n        for i, part in enumerate(parts):\n            walker = walker / part\n            try:\n                m = walker.lstat().st_mode\n            except FileNotFoundError:\n                break\n            if stat.S_ISLNK(m):\n                bad.append(f\"{decl} (symlink at {walker})\"); break\n    return bad\n# run before TaskAssetSnapshot.materialize(clone)","typeGuard":null,"tryCatchPattern":"from eval.workflow_bench.proposer_sandbox import SandboxError\n\ntry:\n    snapshot.materialize(clone)\nexcept SandboxError as exc:\n    if \"cannot be a symlink\" in str(exc) or \"symlink parent\" in str(exc):\n        raise SystemExit(f\"clone has a symlink on a declared root; reset the clone: {exc}\") from exc\n    raise","preventionTips":["Use a fresh clone per run, or `git checkout -f && git clean -fdx` before materialize","Never declare roots that intentionally collide with symlinks in the repo","Run clone_root_is_clean before materialize and abort if non-empty"],"tags":["sandbox","sandbox-copy","symlinks","clone-hygiene"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}