abhigyanpatwari/GitNexus · error · ValueError

task binding count does not match selected tasks

Error message

task binding count does not match selected tasks

What it means

Raised by resolve_task_bindings at the top of the function when the caller passed an `expected` pin list whose length differs from the tasks list (runner_tasks.py:108-109). The expected list is the upstream-immutable pin (one entry per task); a count mismatch means the pin is stale or misaligned.

Source

Thrown at eval/workflow_bench/runner_tasks.py:109

        "expensive": bool(task.get("expensive", False)),
        "sandbox_copy": list(task.get("sandbox_copy", [])),
        "sandbox_dependencies": [dict(item) for item in task.get("sandbox_dependencies", [])],
        **dependency_binding,
        **oracle_snapshot.binding,
    }


def resolve_task_bindings(
    tasks: list[dict[str, Any]],
    expected: list[dict[str, Any]] | None = None,
    *,
    oracle_snapshots: list[TaskOracleSnapshot] | None = None,
    task_asset_cache: TaskAssetCache | None = None,
) -> list[dict[str, Any]]:
    """Resolve each repo/ref once and optionally honor an upstream immutable pin."""

    if expected is not None and len(expected) != len(tasks):
        raise ValueError("task binding count does not match selected tasks")
    snapshots = oracle_snapshots if oracle_snapshots is not None else capture_task_oracles(tasks)
    if len(snapshots) != len(tasks):
        raise ValueError("oracle snapshot count does not match selected tasks")
    bindings: list[dict[str, Any]] = []
    for index, (task, oracle_snapshot) in enumerate(zip(tasks, snapshots, strict=True)):
        requested_repo = Path(task["repo"]).expanduser().resolve()
        repo_output = run_checked(
            ["git", "-C", str(requested_repo), "rev-parse", "--show-toplevel"],
            timeout=60,
        ).stdout_tail.strip()
        repo_identity = Path(repo_output).resolve()
        if expected is None:
            resolved_sha = run_checked(
                [
                    "git",
                    "-C",
                    str(repo_identity),
                    "rev-parse",

View on GitHub (pinned to d540b00184)

Solutions

  1. Regenerate the bindings JSON from the current tasks file (drop --task-bindings-json once to refresh).
  2. Align the task list and the bindings JSON to the same task count and order.
  3. If the pin is intentional, audit which task was added/removed and reconcile.
Defensive patterns

Strategy: validation

Validate before calling

expected = json.load(open("bindings.json")) if path else None
if expected is not None and len(expected) != len(tasks):
    raise SystemExit("regenerate bindings: task count changed")

Type guard

def binding_count_matches(tasks: list, expected: list | None) -> bool:
    return expected is None or len(expected) == len(tasks)

Prevention

When it happens

Trigger: Passing --task-bindings-json from a prior run whose task set changed; adding/removing a task in the YAML without regenerating the bindings JSON; the JSON list being truncated.

Common situations: Editing the tasks file after caching bindings; CI replaying a stale bindings artifact against a newer tasks file.

Related errors


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