{"record":{"id":"33bbf676d887c6ad","repo":"abhigyanpatwari/GitNexus","slug":"candidate-overlay-directory-is-unreadable-direct","errorCode":null,"errorMessage":"candidate overlay directory is unreadable: {directory}: {exc}","messagePattern":"candidate overlay directory is unreadable: (.+?): (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/evolution.py","lineNumber":291,"sourceCode":"    overlay = overlay.expanduser().absolute()\n    try:\n        resolved_overlay = overlay.resolve(strict=True)\n    except OSError as exc:\n        raise ValueError(f\"candidate overlay is not a directory: {overlay}\") from exc\n    if resolved_overlay != overlay:\n        raise ValueError(f\"candidate overlay cannot traverse symlinks: {overlay}\")\n    _require_real_directory(overlay, label=\"candidate overlay\")\n\n    entries: list[Path] = []\n    pending = [overlay]\n    entry_count = 0\n    while pending:\n        directory = pending.pop()\n        child_directories: list[Path] = []\n        try:\n            iterator = os.scandir(directory)\n        except OSError as exc:\n            raise ValueError(f\"candidate overlay directory is unreadable: {directory}: {exc}\") from exc\n        with iterator:\n            for item in iterator:\n                entry_count += 1\n                if entry_count > MAX_CANDIDATE_ENTRIES:\n                    raise ValueError(f\"candidate overlay exceeds the {MAX_CANDIDATE_ENTRIES}-entry limit\")\n                path = Path(item.path)\n                relative = path.relative_to(overlay)\n                if len(relative.as_posix().encode()) > MAX_CANDIDATE_PATH_BYTES:\n                    raise ValueError(f\"candidate overlay path exceeds {MAX_CANDIDATE_PATH_BYTES} bytes: {relative}\")\n                if item.is_symlink():\n                    raise ValueError(f\"candidate overlay cannot contain symlinks: {relative}\")\n                if item.is_dir(follow_symlinks=False):\n                    child_directories.append(path)\n                    continue\n                if not item.is_file(follow_symlinks=False):\n                    raise ValueError(f\"candidate overlay entries must be regular files: {relative}\")\n                entries.append(path)\n                if len(entries) > MAX_CANDIDATE_FILES:","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/evolution.py#L273-L309","documentation":"Thrown by candidate_overlay_files (evolution.py:291) when os.scandir of a directory inside the overlay tree raises OSError during the recursive walk. The top-level directory is already validated; this fires on a subdirectory that cannot be listed — typically a permissions problem (missing read or execute bit) or an I/O error.","triggerScenarios":"A subdirectory of the overlay lacks read or execute permission (EACCES), or scandir hits an I/O error mid-walk (failing disk, vanished mount).","commonSituations":"Overlay created with restrictive umask leaving a subdir mode 0o300 or 0o600; copy from a source that dropped execute bits on directories; overlay partially on an unmounted network share.","solutions":["Fix directory permissions across the overlay so every dir is readable+traversable: find overlay -type d -exec chmod u+rx {} +.","Re-copy the overlay preserving directory execute bits.","Move the overlay onto a healthy local filesystem."],"exampleFix":"# before: a subdir is unreadable -> scandir raises EACCES\n\n# after: ensure every directory is r-x before running\nimport subprocess\nsubprocess.run(['find', str(overlay), '-type', 'd', '-exec', 'chmod', 'u+rxX', {} +'])\n# or in Python:\nfor d in overlay.rglob('*'):\n    if d.is_dir():\n        d.chmod(0o755)","handlingStrategy":"validation","validationCode":"import os\nfrom pathlib import Path\n\ndef overlay_dirs_listable(root: Path) -> bool:\n    for d in [root, *root.rglob('*')]:\n        if d.is_dir():\n            try:\n                list(os.scandir(d))\n            except OSError:\n                return False\n    return True","typeGuard":"null","tryCatchPattern":"try:\n    apply_candidate_overlay(overlay, worktree, sandbox=sandbox)\nexcept ValueError as exc:\n    if 'directory is unreadable' in str(exc):\n        # chmod u+rx on overlay dirs, then retry\n        ...","preventionTips":["Give every overlay directory read+execute bits (chmod -R u+rxX).","Copy overlays with a tool that preserves directory execute bits.","Keep the overlay on a healthy local filesystem."],"tags":["filesystem","permissions","overlay"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}