{"record":{"id":"62478759a8a661af","repo":"abhigyanpatwari/GitNexus","slug":"sanitized-graph-source-changed-while-opening-rel","errorCode":null,"errorMessage":"sanitized graph source changed while opening: {relative}","messagePattern":"sanitized graph source changed while opening: (.+?)","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/sanitized_graph.py","lineNumber":205,"sourceCode":"            if stat.S_ISDIR(metadata.st_mode):\n                pending.append((Path(entry.path), relative))\n                continue\n            if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISREG(metadata.st_mode):\n                continue\n            if metadata.st_size > MAX_GRAPH_SCRUB_FILE_BYTES:\n                continue\n            scanned_bytes += metadata.st_size\n            if scanned_bytes > MAX_GRAPH_SCRUB_TOTAL_BYTES:\n                raise SandboxError(\"sanitized graph source exceeds the scrub byte limit\")\n            descriptor = os.open(entry.path, os.O_RDONLY | getattr(os, \"O_NOFOLLOW\", 0))\n            try:\n                opened = os.fstat(descriptor)\n                if not stat.S_ISREG(opened.st_mode) or (opened.st_dev, opened.st_ino, opened.st_size) != (\n                    metadata.st_dev,\n                    metadata.st_ino,\n                    metadata.st_size,\n                ):\n                    raise SandboxError(f\"sanitized graph source changed while opening: {relative}\")\n                chunks: list[bytes] = []\n                remaining = MAX_GRAPH_SCRUB_FILE_BYTES + 1\n                while remaining > 0:\n                    chunk = os.read(descriptor, min(64 * 1024, remaining))\n                    if not chunk:\n                        break\n                    chunks.append(chunk)\n                    remaining -= len(chunk)\n                payload = b\"\".join(chunks)\n                after = os.fstat(descriptor)\n                if len(payload) != opened.st_size or (opened.st_size, opened.st_mtime_ns, opened.st_ctime_ns) != (\n                    after.st_size,\n                    after.st_mtime_ns,\n                    after.st_ctime_ns,\n                ):\n                    raise SandboxError(f\"sanitized graph source changed while scanning: {relative}\")\n            finally:\n                os.close(descriptor)","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/sanitized_graph.py#L187-L223","documentation":"A TOCTOU guard in the scrubber: after entry.stat() and after os.open+os.fstat, the inode's (st_dev, st_ino, st_size) differs from the stat snapshot, or the descriptor is no longer a regular file. The harness treats any divergence as proof the seed is being mutated and aborts instead of reading uncontrolled bytes.","triggerScenarios":"A file in the seed is replaced/rewritten between the DirEntry.stat call and the os.fstat after os.open inside _scrub_source_references.","commonSituations":"An IDE/git/indexer touching the worktree mid-scrub; two benchmark arms sharing a seed directory; an antivirus or sync daemon rewriting files in place.","solutions":["Guarantee single-writer access to the seed worktree for the whole scrub+build window; the harness already creates one disposable seed per task.","Run on a quiescent filesystem with no indexer/AV/sync daemon touching the clone.","Retry prepare_sanitized_graph once the concurrent writer is gone; the seed is rebuilt fresh by make_worktree."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import fcntl, os\n\ndef take_tree_lock(path):\n    \"\"\"Acquire an exclusive flock on the seed root to prevent concurrent mutation.\"\"\"\n    fd = os.open(path, os.O_RDONLY | os.O_DIRECTORY)\n    fcntl.flock(fd, fcntl.LOCK_EX)\n    return fd","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guarantee single-writer access to the seed for the whole scrub+build window.","Run on a quiescent filesystem with no indexer, AV, or sync daemon.","Retry prepare_sanitized_graph after stopping any concurrent writer; the seed is rebuilt fresh."],"tags":["sandbox","toctou","filesystem","workflow-bench"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}