{"record":{"id":"acf2f629d1cf5c0d","repo":"abhigyanpatwari/GitNexus","slug":"overlay-destination-parent-is-unavailable-target","errorCode":null,"errorMessage":"overlay destination parent is unavailable: {target}","messagePattern":"overlay destination parent is unavailable: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/promotion_apply.py","lineNumber":201,"sourceCode":"        os.close(descriptor)\n        raise ValueError(f\"repository root changed while opening: {root}\") from exc\n    except BaseException:\n        os.close(descriptor)\n        raise\n    return root, descriptor\n\n\ndef _open_target_parent(root_descriptor: int, target: PurePosixPath) -> int:\n    if target.is_absolute() or not target.parts or \"..\" in target.parts:\n        raise ValueError(f\"overlay destination escapes repository: {target}\")\n    flags = os.O_RDONLY | os.O_DIRECTORY | getattr(os, \"O_CLOEXEC\", 0) | getattr(os, \"O_NOFOLLOW\", 0)\n    current = os.dup(root_descriptor)\n    try:\n        for part in target.parts[:-1]:\n            try:\n                metadata = os.stat(part, dir_fd=current, follow_symlinks=False)\n            except OSError as exc:\n                raise ValueError(f\"overlay destination parent is unavailable: {target}\") from exc\n            if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):\n                raise ValueError(f\"overlay destination parent must not be a symlink: {target}\")\n            try:\n                child = os.open(part, flags, dir_fd=current)\n            except OSError as exc:\n                raise ValueError(f\"overlay destination parent changed while opening: {target}\") from exc\n            opened = os.fstat(child)\n            if (\n                opened.st_dev,\n                opened.st_ino,\n                stat.S_IFMT(opened.st_mode),\n            ) != (\n                metadata.st_dev,\n                metadata.st_ino,\n                stat.S_IFMT(metadata.st_mode),\n            ):\n                os.close(child)\n                raise ValueError(f\"overlay destination parent changed while opening: {target}\")","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/promotion_apply.py#L183-L219","documentation":"All errors below are raised by internal helpers of `eval/workflow_bench/promotion_apply.py` and propagate to the caller of the public entry points: `apply_promoted_overlay(overlay, repo_root, *, expected_digest, expected_target_bases)`, `destination_base_digests(overlay, repo_root)`, `committed_destination_base_digests(overlay, repo_root, *, ref)` and `freeze_overlay(overlay, destination)`. The module applies promoted skill overlays across the canonical skill tree plus its shipped mirrors (`gitnexus/skills`, `gitnexus-claude-plugin/skills`) in a TOCTOU-hardened, symlink-rejecting, descriptor-bound transaction. In `_open_target_parent`'s per-component walk, `os.stat(part, dir_fd=current, follow_symlinks=False)` raised `OSError`. An intermediate directory component named by `part` does not exist or is inaccessible relative to the held descriptor, so the target's parent chain cannot be walked.","triggerScenarios":"An overlay target whose parent directory (or an intermediate component) does not exist in the checkout, or is unreadable; e.g. the overlay declares a path under a skill name that was never created.","commonSituations":"Promoting an overlay for a skill not yet present in the mirror roots; a partially cloned checkout missing a subdirectory; permission drop on an intermediate dir.","solutions":["Check the target's parent exists: `Path(root / target.parent).is_dir()`.","Create the missing mirror directory in the checkout (the API does NOT mkdir).","Re-derive the overlay payload so it only targets existing skill paths."],"exampleFix":"// before\napply_promoted_overlay(overlay, repo_root=root)\n// after\nfor rel,_ in candidate_overlay_payload(overlay)[1]:\n    for t in mirror_targets(rel):\n        parent = root / t.parent\n        if not parent.is_dir():\n            raise SystemExit(f'missing parent dir: {parent}')\napply_promoted_overlay(overlay, repo_root=root)","handlingStrategy":"validation","validationCode":"def assert_parents_exist(root, payload):\n    for rel, _ in payload:\n        for t in mirror_targets(rel):\n            parent = root / t.parent\n            if not parent.is_dir():\n                raise ValueError(f'missing parent: {parent}')\nassert_parents_exist(root, candidate_overlay_payload(overlay)[1])","typeGuard":"def all_parents_exist(root, payload) -> bool:\n    return all(\n        (root / t.parent).is_dir()\n        for rel, _ in payload for t in mirror_targets(rel)\n    )","tryCatchPattern":"except ValueError as exc:\n    if 'parent is unavailable' in str(exc):\n        raise SystemExit(f'overlay target parent missing; create the mirror dir first: {exc}')","preventionTips":["Ensure the full mirror skill tree exists before promoting (the API replaces files, it does not create directories).","Validate `all_parents_exist` against the payload before applying.","Clone a complete checkout, not a sparse/partial one, for promotion."],"tags":["filesystem","missing-directory","validation","overlay"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}