abhigyanpatwari/GitNexus · error · SandboxError
sanitized graph asset must be regular and non-symlink: {path
Error message
sanitized graph asset must be regular and non-symlink: {path} What it means
In _validate_graph_metadata, each of .gitnexus/{gitnexus.json,meta.json,lbug} must be a regular non-symlink file (checked via lstat). A symlink or special file would let the target swap metadata after validation, so the harness rejects it.
Source
Thrown at eval/workflow_bench/sanitized_graph.py:321
"-r",
"benchmark-target",
"--limit",
"1",
),
timeout=GRAPH_QUERY_TIMEOUT_SECONDS,
capture_stdout=True,
)
assert node_result is not None and relation_result is not None
_parse_empty_query(node_result, label="sanitized graph node proof")
_parse_empty_query(relation_result, label="sanitized graph relation proof")
def _validate_graph_metadata(root: Path, sanitized_head: str) -> None:
for name in ("gitnexus.json", "meta.json", "lbug"):
path = root / ".gitnexus" / name
metadata = path.lstat()
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISREG(metadata.st_mode):
raise SandboxError(f"sanitized graph asset must be regular and non-symlink: {path}")
try:
metadata_payload = json.loads((root / ".gitnexus" / "gitnexus.json").read_text())
except (OSError, json.JSONDecodeError) as exc:
raise SandboxError("sanitized graph metadata is malformed") from exc
if metadata_payload.get("lastCommit") != sanitized_head:
raise SandboxError("sanitized graph metadata is not bound to the parentless task commit")
if not isinstance(metadata_payload.get("pdg"), dict) or not metadata_payload["pdg"]:
raise SandboxError("sanitized graph metadata does not prove a --pdg build")
def prepare_sanitized_graph(
task: Mapping[str, Any],
*,
repo: Path,
resolved_sha: str,
parent: Path,
cache: TaskAssetCache,
claude_bin: Path | str,View on GitHub (pinned to d540b00184)
Solutions
- Replace symlinked/special metadata files with real regular files, or remove .gitnexus so the harness rebuilds it.
- Audit task declarations and validate_no_prebuilt_graph_assets to ensure no sandbox_copy/dependency imports .gitnexus/*.
- Re-run graph preparation so the harness owns those files itself.
Defensive patterns
Strategy: validation
Validate before calling
import os, stat
def assert_graph_assets_regular(root):
for name in ("gitnexus.json", "meta.json", "lbug"):
p = os.path.join(root, ".gitnexus", name)
m = os.lstat(p)
if stat.S_ISLNK(m.st_mode) or not stat.S_ISREG(m.st_mode):
raise RuntimeError(f"{p} must be a regular non-symlink file") Prevention
- Never symlink .gitnexus metadata files; let the harness build and own them.
- Ensure validate_no_prebuilt_graph_assets blocks any sandbox_copy/dependency importing .gitnexus/*.
- Remove a pre-existing .gitnexus before graph preparation so it is rebuilt cleanly.
When it happens
Trigger: The target repo supplies .gitnexus/gitnexus.json (or meta.json/lbug) as a symlink to an external file, or as a FIFO/device/socket.
Common situations: A task reuses a prebuilt index by symlinking .gitnexus; a packaging step created the metadata via symlink; a tampering attempt to bind foreign metadata.
Related errors
- evidence source must be a regular non-symlink file: {path}
- results directory must not traverse symlinks: {root}
- results artifact parent must be a real directory: {current}
- transcript artifact parent must be owner-only: {current}
- {label} must be a real directory: {root}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/af44ad458c682f2e.
Report an issue: GitHub.