{"record":{"id":"cb4a4dee9f0a3ac1","repo":"abhigyanpatwari/GitNexus","slug":"oracle-worktree-must-be-a-real-non-symlink-directo","errorCode":null,"errorMessage":"oracle worktree must be a real non-symlink directory: {root}","messagePattern":"oracle worktree must be a real non-symlink directory: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/oracle_assets.py","lineNumber":514,"sourceCode":"        current = stage_root\n        for part in relative.parts[:-1]:\n            current /= part\n            metadata = current.lstat()\n            if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):\n                raise ValueError(f\"oracle stage parent changed during verification: {item.target}\")\n        observed = _read_oracle_file(stage_root, relative)\n        if observed != item.payload:\n            raise ValueError(f\"oracle file changed during verification: {item.target}\")\n\n\n@contextmanager\ndef staged_task_oracle(worktree: Path, snapshot: TaskOracleSnapshot) -> Iterator[Path]:\n    \"\"\"Materialize a private random oracle root only after the model exits.\"\"\"\n\n    root = worktree.expanduser().absolute()\n    metadata = root.lstat()\n    if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode) or root.resolve(strict=True) != root:\n        raise ValueError(f\"oracle worktree must be a real non-symlink directory: {root}\")\n    stage_root = root / f\".wfbench-oracle-{secrets.token_hex(16)}\"\n    stage_root.mkdir(mode=0o700)\n    stage_root.chmod(0o700)\n    primary: BaseException | None = None\n    try:\n        for item in snapshot.files:\n            _write_stage_file(stage_root, item)\n        yield stage_root\n        _verify_staged_oracle(stage_root, snapshot)\n    except BaseException as exc:\n        primary = exc\n        raise\n    finally:\n        try:\n            mode = stage_root.lstat().st_mode\n            if stat.S_ISLNK(mode):\n                stage_root.unlink()\n            elif stat.S_ISDIR(mode):","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/oracle_assets.py#L496-L532","documentation":"Entry guard of the staged_task_oracle context manager: the user-supplied worktree must exist, be a real (non-symlink) directory, and resolve(strict=True) to itself (no symlink in any path component). This is a precondition failure before any staging begins, so it is caller-fixable rather than evidence of tampering.","triggerScenarios":"Raised immediately when staged_task_oracle(worktree, snapshot) is called and worktree is missing, is a regular file, is a symlink, or contains a symlink in its path components (root.resolve(strict=True) != root).","commonSituations":"Passing a path that is a symlink to the real worktree (common in CI with workspace shortcuts); pointing at the worktree before cloning; passing the repository root file itself; Mac /tmp is a symlink to /private/tmp — `Path('/tmp/x')` resolves to `/private/tmp/x`.","solutions":["Pass worktree.expanduser().resolve() (or an already-resolved real directory) into staged_task_oracle.","Ensure the worktree directory exists and is created by the caller (e.g. git clone / mkdir) before invocation.","On macOS avoid /tmp literally — use /private/tmp or a path under the project dir, or resolve() first.","Verify with `Path(p).is_dir() and not Path(p).is_symlink()` before the call."],"exampleFix":"// before\nwith staged_task_oracle(Path('/tmp/wfbench'), snap) as r: ...\n// after\nroot = Path('/tmp/wfbench').expanduser().resolve()\nassert root.is_dir() and not root.is_symlink()\nwith staged_task_oracle(root, snap) as r: ...","handlingStrategy":"validation","validationCode":"import stat\nfrom pathlib import Path\n\ndef resolve_worktree(p: str | Path) -> Path:\n    root = Path(p).expanduser().absolute()\n    meta = root.lstat()\n    if stat.S_ISLNK(meta.st_mode) or not stat.S_ISDIR(meta.st_mode):\n        raise ValueError(f'{root} must be a real non-symlink directory')\n    if root.resolve(strict=True) != root:\n        raise ValueError(f'{root} contains a symlink component; use {root.resolve()}')\n    return root\n\n# then: with staged_task_oracle(resolve_worktree(path), snapshot) as r: ...","typeGuard":"from pathlib import Path\nimport stat\n\ndef is_real_directory(p: str | Path) -> bool:\n    path = Path(p)\n    try:\n        meta = path.lstat()\n    except (FileNotFoundError, NotADirectoryError):\n        return False\n    return stat.S_ISDIR(meta.st_mode) and not stat.S_ISLNK(meta.st_mode) and path.resolve(strict=True) == path","tryCatchPattern":"try:\n    with staged_task_oracle(worktree, snapshot) as stage:\n        ...\nexcept ValueError as exc:\n    if 'must be a real non-symlink directory' in str(exc):\n        worktree = Path(worktree).resolve()\n        # retry once with the resolved path","preventionTips":["Always pass `Path(worktree).expanduser().resolve()` rather than raw input.","On macOS avoid /tmp — use /private/tmp or a path under the project.","Reject user-supplied paths that contain symlinks at the config boundary."],"tags":["oracle","validation","symlink","worktree","precondition"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}