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

  1. Replace symlinked/special metadata files with real regular files, or remove .gitnexus so the harness rebuilds it.
  2. Audit task declarations and validate_no_prebuilt_graph_assets to ensure no sandbox_copy/dependency imports .gitnexus/*.
  3. 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

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


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/af44ad458c682f2e. Report an issue: GitHub.