abhigyanpatwari/GitNexus · error · SandboxError
{label} does not exist: {relative}
Error message
{label} does not exist: {relative} What it means
Raised by _safe_repo_source, the trust-boundary validator for any task-declared repo-relative asset source. After confirming the path is repo-relative and cannot escape the repository root, it requires the resolved path to actually exist on disk; a missing file or directory is rejected because the subsequent read-only bubblewrap mount would silently fail or, worse, be redirected. This runs before containment starts, so the harness refuses to stage a non-existent asset rather than weaken the contract.
Source
Thrown at eval/workflow_bench/proposer_sandbox.py:572
except OSError as exc:
raise SandboxError(f"{label} must be a real directory: {lexical}: {exc}") from exc
if resolved != lexical:
raise SandboxError(f"{label} must not traverse symlinks: {lexical}")
return lexical
def _safe_repo_source(repo: Path, relative: str, *, label: str) -> tuple[Path, Path]:
candidate = PurePosixPath(relative)
if candidate.is_absolute() or ".." in candidate.parts or not candidate.parts:
raise SandboxError(f"{label} must be a repository-relative path: {relative!r}")
lexical = repo / Path(*candidate.parts)
resolved = lexical.resolve()
try:
resolved.relative_to(repo)
except ValueError as exc:
raise SandboxError(f"{label} escapes its allowed repository root: {relative}") from exc
if not resolved.exists():
raise SandboxError(f"{label} does not exist: {relative}")
return lexical, resolved
def _prepare_clone_target(
clone: Path,
relative: PurePosixPath,
*,
directory: bool | None,
label: str,
) -> Path:
"""Validate/create a clone-local target without following any symlink.
This runs before Bubblewrap, so ordinary ``Path.mkdir``/``touch`` calls
are not acceptable: an untrusted tracked parent symlink could redirect a
mount placeholder write into the host filesystem.
"""
flags = os.O_RDONLY | os.O_DIRECTORY | getattr(os, "O_CLOEXEC", 0)View on GitHub (pinned to d540b00184)
Solutions
- Copy the exact relative path from the error and run `ls -la <repo>/<relative>` against the repo root the harness uses (the worktree at the task SHA, not your working copy).
- Confirm the asset is committed at that relative path in the resolved SHA: `git -C <repo> cat-file -e <sha>:<relative>`.
- If the path is wrong, fix the source/asset entry in the task YAML to the correct repository-relative path.
- If the asset is produced dynamically, ensure the producing step runs before staging and writes into the same worktree the harness will bind.
Example fix
// task YAML (before) assets: - source: eval/workflow_bench/fixtures/NodeModules.json // after — corrected relative path that exists in the repo assets: - source: eval/workflow_bench/fixtures/node_modules.json
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path, PurePosixPath
def assert_repo_source_exists(repo: Path, relative: str) -> None:
cand = PurePosixPath(relative)
assert not cand.is_absolute() and '..' not in cand.parts and cand.parts, relative
resolved = (repo / Path(*cand.parts)).resolve()
resolved.relative_to(repo) # raises ValueError if it escapes
assert resolved.exists(), f'{relative} does not exist under {repo}' Try / catch
from .proposer_sandbox import SandboxError
try:
lexical, resolved = _safe_repo_source(repo, relative, label='asset')
except SandboxError as exc:
# surface to the task author; do not proceed to staging
raise Prevention
- Author task asset paths as repository-relative, case-checked against a case-sensitive checkout.
- Validate every task file's asset paths against the repo in CI before running the harness.
- Run the harness from a stable CWD and pass --repo explicitly.
When it happens
Trigger: A task YAML entry declares a dependency/asset source path (e.g. a node_modules snapshot, a fixture, or a config file) whose relative path does not exist under the resolved repo root at the task's checked-out SHA. Concretely: stage_task_assets -> _safe_repo_source(repo, relative, label=...) where Path(repo / relative).resolve().exists() is False.
Common situations: Path typo or wrong casing in the task file (especially macOS dev authoring vs. case-sensitive Linux CI); asset was renamed/moved after the task was authored; harness invoked from a different CWD or with a different --repo so 'repo' resolves elsewhere; asset exists only on a branch that is not checked out; the asset is generated by a setup step that ran in a different worktree.
Related errors
- {label} target has a non-directory or symlink parent: {relat
- {label} target cannot be a symlink: {relative}
- {label} directory target has the wrong type: {relative}
- {label} file target has the wrong type: {relative}
- {label} target has the wrong type: {relative}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/249514efae226cc2.
Report an issue: GitHub.