abhigyanpatwari/GitNexus · error · SandboxError

sandbox_copy exceeds the path byte limit

Error message

sandbox_copy exceeds the path byte limit

What it means

Raised by _validate_manifest_path when len(relative.as_posix().encode('utf-8')) exceeds MAX_TASK_ASSET_PATH_BYTES (4096, the Linux PATH_MAX). This is a containment guard so one pathological declaration cannot turn manifest/digest computation or the materialization walk into an unbounded or kernel-rejected operation.

Source

Thrown at eval/workflow_bench/task_assets.py:894

def _mutation_identity(metadata: os.stat_result) -> tuple[int, int, int, int, int, int]:
    return (
        metadata.st_dev,
        metadata.st_ino,
        metadata.st_mode,
        metadata.st_size,
        metadata.st_mtime_ns,
        metadata.st_ctime_ns,
    )


def _validate_manifest_path(relative: PurePosixPath) -> None:
    try:
        path_bytes = len(relative.as_posix().encode("utf-8"))
    except UnicodeEncodeError as exc:
        raise SandboxError(f"sandbox_copy path is not valid UTF-8: {relative!s}") from exc
    if path_bytes > MAX_TASK_ASSET_PATH_BYTES:
        raise SandboxError("sandbox_copy exceeds the path byte limit")


def _manifest_digest(entries: tuple[AssetManifestEntry, ...]) -> str:
    payload = [
        {
            "kind": entry.kind,
            "link_target": entry.link_target,
            "mode": entry.mode,
            "path": entry.path.as_posix(),
            "sha256": entry.sha256,
            "size": entry.size,
        }
        for entry in entries
    ]
    return hashlib.sha256(json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()).hexdigest()


def _dependency_digests(dependencies: tuple[DependencySnapshot, ...]) -> tuple[str, str]:

View on GitHub (pinned to d540b00184)

Solutions

  1. Shorten the declaration: use a repo-relative path and/or reorganize so the asset lives shallower in the tree.
  2. If the long path is generated output, exclude it from sandbox_copy and regenerate it inside the clone instead.
  3. Only raise MAX_TASK_ASSET_PATH_BYTES if you are certain every consumer (kernel, filesystem, JSON digest) accepts paths that long; 4096 is the safe portable ceiling.

Example fix

# before: deeply nested generated path exceeds 4096 bytes
sandbox_copy = ['src/gen/a0/b1/c2/.../very/deeply/nested/index.bin']

# after: capture a shallower root and let the arm find the file under it
sandbox_copy = ['src/gen']
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import PurePosixPath

MAX_TASK_ASSET_PATH_BYTES = 4096

def assert_path_length(relative: PurePosixPath) -> None:
    n = len(relative.as_posix().encode('utf-8'))
    if n > MAX_TASK_ASSET_PATH_BYTES:
        raise ValueError(f'sandbox_copy path exceeds {MAX_TASK_ASSET_PATH_BYTES} bytes: {relative}')

# Validate every declared source/target before cache.prepare.

Type guard

def path_within_limit(relative: PurePosixPath, limit: int = 4096) -> bool:
    return len(relative.as_posix().encode('utf-8')) <= limit

Prevention

When it happens

Trigger: A sandbox_copy entry whose declared relative path is longer than 4096 bytes once UTF-8 encoded. Happens with deeply nested generated trees, hashed/bazel-style output paths, or a declaration that captures an absolute path with many components instead of a relative one.

Common situations: Pointing sandbox_copy at a node_modules/.cache or build output tree with very long paths; using full absolute repo paths instead of repo-relative ones; declaration globbing captured an unexpectedly deep generated directory.

Related errors


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