abhigyanpatwari/GitNexus · error · SandboxError
results artifact parent is unavailable: {current}: {exc}
Error message
results artifact parent is unavailable: {current}: {exc} What it means
While _results_artifact_path walks each parent component of a (shape-valid) artifact path, it lstat's every parent dir. An OSError on a parent becomes SandboxError. By this point the leaf shape is already validated, so a missing parent means the results tree is internally inconsistent.
Source
Thrown at eval/workflow_bench/evolve.py:317
def _results_artifact_path(root: Path, relative_value: str, *, transcript: bool) -> Path:
relative = PurePosixPath(relative_value)
expected_parts = 2 if transcript else 1
if (
relative.is_absolute()
or len(relative.parts) != expected_parts
or any(part in {"", ".", ".."} for part in relative.parts)
or (transcript and relative.parts[0] != "transcripts")
):
raise SandboxError(f"unsafe results artifact path: {relative_value!r}")
current = root
for part in relative.parts[:-1]:
current /= part
try:
metadata = current.lstat()
except OSError as exc:
raise SandboxError(f"results artifact parent is unavailable: {current}: {exc}") from exc
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
raise SandboxError(f"results artifact parent must be a real directory: {current}")
if transcript and stat.S_IMODE(metadata.st_mode) & 0o077:
raise SandboxError(f"transcript artifact parent must be owner-only: {current}")
return root / Path(*relative.parts)
def _transcript_artifact_metadata(metadata: Any) -> tuple[str, str, int]:
"""Validate transcript metadata without touching any host path."""
if not isinstance(metadata, dict) or set(metadata) != {"path", "sha256", "bytes", "source"}:
raise SandboxError("transcript artifact metadata must contain only path, sha256, bytes, and source")
relative = metadata["path"]
expected_digest = metadata["sha256"]
expected_size = metadata["bytes"]
if metadata["source"] != runner_sessions.PARENT_EVENT_STREAM_SOURCE:
raise SandboxError("transcript artifact source is not the parent event stream")
if not isinstance(relative, str) or not re.fullmatch(r"[0-9a-f]{64}", str(expected_digest)):View on GitHub (pinned to d540b00184)
Solutions
- Verify the printed parent path exists: `ls -ld <results_dir>/<parent>`.
- Re-run the benchmark so the results tree and its rows are written together atomically.
- Restore the missing parent from a backup or regenerate the results.
Example fix
# before: results.jsonl references transcripts/run-42.json but transcripts/ was deleted # after: regenerate results so the dir and its rows agree rm -rf results/ && uv run workflow_bench # rewrites results.jsonl + transcripts/ together
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def artifact_parents_available(root: Path, relative_value: str) -> bool:
current = root
for part in PurePosixPath(relative_value).parts[:-1]:
current /= part
try:
current.lstat()
except OSError:
return False
return True Prevention
- Write results.jsonl and the artifact dirs atomically (together) so they never disagree.
- Don't delete transcript dirs between generations.
- Regenerate results if any parent is missing rather than patching rows by hand.
When it happens
Trigger: A transcript path 'transcripts/run-42.json' is recorded but the 'transcripts' directory does not exist or is unreadable; a parent was deleted between results.jsonl write and read.
Common situations: Partial/corrupted results writes; a cleanup job that removed transcript dirs; permissions changed between generations; results copied without preserving directory structure.
Related errors
- results directory is unavailable: {root}: {exc}
- results directory must be a real non-symlink directory: {roo
- results directory must not traverse symlinks: {root}
- evidence source must be a regular non-symlink file: {path}
- results artifact parent must be a real directory: {current}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/d9e37fbf02eebd47.
Report an issue: GitHub.