abhigyanpatwari/GitNexus · error · SandboxError

task asset snapshot does not match this dependency declarati

Error message

task asset snapshot does not match this dependency declaration

What it means

Raised by _dependency_mounts when the snapshot's recorded dependency_declarations (tuples of (source,target)) do not equal the (source,target) pairs parsed from the current task's sandbox_dependencies. The snapshot must have been built from exactly the same dependency declarations as the task being staged, otherwise the dependency mounts would not correspond to real captured bytes.

Source

Thrown at eval/workflow_bench/task_assets.py:1053

        "sandbox_dependencies": task.get("sandbox_dependencies", []),
    }
    with tempfile.TemporaryDirectory(prefix="wfbench-dependency-binding-") as temporary:
        with TaskAssetCache(Path(temporary) / "cache") as cache:
            snapshot = cache.prepare(dependency_task, repo=repo, resolved_sha=resolved_sha)
            return snapshot.dependency_binding


def _dependency_mounts(
    task: Mapping[str, Any],
    *,
    clone: Path,
    snapshot: TaskAssetSnapshot,
) -> list[ReadOnlyMount]:
    declarations = tuple(
        (declaration.source, declaration.target) for declaration in _sandbox_dependency_declarations(task)
    )
    if snapshot.dependency_declarations != declarations:
        raise SandboxError("task asset snapshot does not match this dependency declaration")
    return snapshot.dependency_mounts(clone)


def stage_task_assets(
    task: Mapping[str, Any],
    *,
    repo: Path,
    clone: Path,
    snapshot: TaskAssetSnapshot | None = None,
) -> list[ReadOnlyMount]:
    """Materialize copied assets and validate read-only dependency mounts.

    ``snapshot`` is supplied by the benchmark runner so every arm reuses one
    capture.  The optional path preserves the historic standalone helper API
    for containment tests and external callers.
    """

    repo_identity = _real_directory(repo, label="task asset repository")

View on GitHub (pinned to d540b00184)

Solutions

  1. Prepare the snapshot from the exact same task dict you later stage: same sandbox_dependencies list, same order, same source/target strings.
  2. If you reuse snapshots across tasks, key them by the full task declaration (including sandbox_dependencies), not just repo_identity + sandbox_copy.
  3. Do not reorder or edit sandbox_dependencies entries between cache.prepare and stage_task_assets.

Example fix

# before: snapshot built from task A, staged against task B (different deps)
snapshot = cache.prepare(task_a, repo=repo, resolved_sha=sha)
stage_task_assets(task_b, repo=repo, clone=clone, snapshot=snapshot)  # -> mismatch

# after: build and stage from the same task object
task = load_task(...)
snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
stage_task_assets(task, repo=repo, clone=clone, snapshot=snapshot)
Defensive patterns

Strategy: validation

Validate before calling

from .task_assets import _sandbox_dependency_declarations

def assert_snapshot_matches_deps(task, snapshot) -> None:
    decls = tuple((d.source, d.target) for d in _sandbox_dependency_declarations(task))
    if snapshot.dependency_declarations != decls:
        raise ValueError(
            f'snapshot deps {snapshot.dependency_declarations!r} != task deps {decls!r}; '
            'prepare the snapshot from this exact task.'
        )

# Call before stage_task_assets; rebuild the snapshot if it does not match.

Type guard

def snapshot_matches_deps(task, snapshot) -> bool:
    decls = tuple((d.source, d.target) for d in _sandbox_dependency_declarations(task))
    return snapshot.dependency_declarations == decls

Try / catch

from .proposer_sandbox import SandboxError

try:
    stage_task_assets(task, repo=repo, clone=clone, snapshot=snapshot)
except SandboxError as exc:
    if 'does not match this dependency declaration' in str(exc):
        # Rebuild snapshot from the current task and retry exactly once.
        with TaskAssetCache(cache_dir) as cache:
            snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
        stage_task_assets(task, repo=repo, clone=clone, snapshot=snapshot)
    else:
        raise

Prevention

When it happens

Trigger: stage_task_assets is called with a snapshot built from a task whose sandbox_dependencies list differs (added/removed/reordered/edited source or target) from the task passed to stage_task_assets. The snapshot check at line 1074 passed (same repo_identity and sandbox_copy declarations) but the dependency list diverged.

Common situations: Two tasks share the same sandbox_copy but different sandbox_dependencies, and the runner hands the wrong snapshot to one; editing a dependency target between snapshot prepare and stage; reordering sandbox_dependencies entries (the comparison is positional tuple equality).

Related errors


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