{"record":{"id":"51b357f5e70b22b0","repo":"abhigyanpatwari/GitNexus","slug":"dependency-snapshot-changed-dependency-source","errorCode":null,"errorMessage":"dependency snapshot changed: {dependency.source}","messagePattern":"dependency snapshot changed: (.+?)","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/task_assets.py","lineNumber":170,"sourceCode":"        finally:\n            shutil.rmtree(staging, ignore_errors=True)\n\n    def dependency_mounts(self, clone: Path) -> list[ReadOnlyMount]:\n        \"\"\"Mount only immutable captured dependency roots into an arm clone.\"\"\"\n\n        clone = _real_directory(clone, label=\"dependency clone\")\n        snapshot_root = _real_directory(self.root, label=\"task asset snapshot\")\n        mounts: list[ReadOnlyMount] = []\n        for dependency in self.dependencies:\n            source = snapshot_root / Path(*dependency.snapshot_path.parts)\n            metadata = source.lstat()\n            expected_directory = dependency.kind == \"directory\"\n            if (\n                stat.S_ISLNK(metadata.st_mode)\n                or (expected_directory and not stat.S_ISDIR(metadata.st_mode))\n                or (not expected_directory and not stat.S_ISREG(metadata.st_mode))\n            ):\n                raise SandboxError(f\"dependency snapshot changed: {dependency.source}\")\n            target = PurePosixPath(dependency.target)\n            _prepare_clone_target(\n                clone,\n                target,\n                directory=expected_directory,\n                label=\"dependency\",\n            )\n            mounts.append(\n                ReadOnlyMount(\n                    source=source,\n                    target=f\"{SANDBOX_WORKSPACE}/{target.as_posix()}\",\n                )\n            )\n        return mounts\n\n\nclass TaskAssetCache:\n    \"\"\"Own immutable snapshots for one benchmark invocation.\"\"\"","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/task_assets.py#L152-L188","documentation":"In TaskAssetSnapshot.dependency_mounts, each dependency's captured source under the frozen snapshot root must still be the expected type (directory or regular file) and must not be a symlink. If lstat disagrees with what was captured, the snapshot was mutated and the mount is refused.","triggerScenarios":"Between snapshot capture and dependency_mounts (called per arm), the frozen snapshot's dependency path became a symlink or changed type - e.g. _freeze_snapshot did not actually lock it, or an external process mutated the nominally-immutable tree.","commonSituations":"A bug in freeze/thaw leaving the snapshot writable; concurrent arms racing on a shared cache root; external tampering with the cache directory.","solutions":["Confirm _freeze_snapshot ran on the snapshot and the tree is mode 0500/0400.","Ensure the cache root is single-writer and not shared across benchmark processes that could mutate it.","Re-capture the snapshot (drop the cache entry) so it is freshly frozen."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os, stat\nfrom pathlib import Path\n\ndef assert_dependency_snapshot_intact(snapshot_root, dependencies):\n    for dep in dependencies:\n        src = Path(snapshot_root, *dep.snapshot_path.parts)\n        m = src.lstat()\n        expected_dir = dep.kind == \"directory\"\n        if stat.S_ISLNK(m.st_mode):\n            raise RuntimeError(f\"dependency snapshot became a symlink: {dep.source}\")\n        if expected_dir and not stat.S_ISDIR(m.st_mode):\n            raise RuntimeError(f\"dependency snapshot not a directory: {dep.source}\")\n        if not expected_dir and not stat.S_ISREG(m.st_mode):\n            raise RuntimeError(f\"dependency snapshot not a regular file: {dep.source}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm _freeze_snapshot ran and the cache tree is mode 0500/0400.","Keep the cache root exclusive to one TaskAssetCache; do not share across processes.","Re-capture the snapshot if any dependency path is mutated."],"tags":["integrity","sandbox","workflow-bench","toctou"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}