{"record":{"id":"8e490d0d8f386476","repo":"abhigyanpatwari/GitNexus","slug":"compound-engineering-plugin-directory-is-unreadabl","errorCode":null,"errorMessage":"Compound Engineering plugin directory is unreadable: {directory}: {exc}","messagePattern":"Compound Engineering plugin directory is unreadable: (.+?): (.+?)","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/runtime_mounts.py","lineNumber":317,"sourceCode":"    required_manifest = _ALLOWED_PLUGIN_MANIFESTS[0]\n    manifest_path = source / Path(*required_manifest.parts)\n    if not manifest_path.exists():\n        raise SandboxError(f\"Compound Engineering plugin manifest is missing: {manifest_path}\")\n    for relative in _ALLOWED_PLUGIN_MANIFESTS:\n        candidate = source / Path(*relative.parts)\n        if candidate.exists():\n            yield relative, candidate\n\n    skills = source / \"skills\"\n    if not skills.exists():\n        raise SandboxError(f\"Compound Engineering plugin skills directory is missing: {skills}\")\n\n    def walk(directory: Path, relative_dir: PurePosixPath) -> Iterator[tuple[PurePosixPath, Path]]:\n        try:\n            with os.scandir(directory) as scanned:\n                entries = sorted(scanned, key=lambda entry: entry.name)\n        except OSError as exc:\n            raise SandboxError(f\"Compound Engineering plugin directory is unreadable: {directory}: {exc}\") from exc\n        for entry in entries:\n            relative = relative_dir / entry.name\n            if _is_forbidden_plugin_path(relative):\n                continue\n            try:\n                metadata = entry.stat(follow_symlinks=False)\n            except OSError as exc:\n                raise SandboxError(f\"Compound Engineering plugin entry is unreadable: {entry.path}: {exc}\") from exc\n            if stat.S_ISLNK(metadata.st_mode):\n                raise SandboxError(f\"Compound Engineering plugin entries must not be symlinks: {entry.path}\")\n            if stat.S_ISDIR(metadata.st_mode):\n                yield from walk(Path(entry.path), relative)\n            elif stat.S_ISREG(metadata.st_mode):\n                yield relative, Path(entry.path)\n            else:\n                raise SandboxError(f\"Compound Engineering plugin entries must be regular files: {entry.path}\")\n\n    for name in _ALLOWED_PLUGIN_DIRS:","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/runtime_mounts.py#L299-L335","documentation":"Inside the recursive walk() over skills/scripts/assets, os.scandir() failure on any directory raises SandboxError with this message. The harness will not silently skip an unreadable subtree.","triggerScenarios":"Permission denied (EACCES) on a subdirectory under skills/, scripts/, or assets/; I/O error (EIO) on the underlying filesystem; directory removed mid-scan.","commonSituations":"Restrictive ACLs applied to part of the plugin tree; container with read-only bind mounts that omit execute permission; concurrent modification during snapshot build.","solutions":["Grant read+execute on the whole tree: `chmod -R +rX <plugin_dir>`.","Re-extract the plugin from a clean tarball to eliminate ACL drift.","Ensure no process is modifying the plugin source while the snapshot is being built."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\nfrom pathlib import Path\n\ndef plugin_dirs_scannable(source: Path) -> bool:\n    for name in (\"skills\", \"scripts\", \"assets\"):\n        d = source / name\n        if not d.exists():\n            continue\n        try:\n            with os.scandir(d):\n                pass\n        except OSError:\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    list(_plugin_files(source))\nexcept SandboxError as exc:\n    if \"directory is unreadable\" in str(exc):\n        # chmod -R +rX the plugin source, or copy to a stable local path\n        ...\n    raise","preventionTips":["Run `chmod -R +rX` on the plugin source before benchmarking.","Copy the plugin to a local readonly directory and point --ce-plugin-dir there."],"tags":["ce-plugin","permissions","filesystem","sandbox"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}