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
- Regenerate the bindings JSON from the current tasks file (drop --task-bindings-json once to refresh).
- Align the task list and the bindings JSON to the same task count and order.
- 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
- Regenerate the bindings JSON whenever the task list changes.
- Commit tasks and bindings together so they stay aligned.
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
- task {task['id']} did not resolve to an immutable commit
- task binding definition drifted for {task['id']}
- {flag} must name a nonblank, versioned model
- {flag} must not use a mutable auto/latest model alias: {mode
- oracle snapshot count does not match selected tasks
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/d676a1b19b0db4da.
Report an issue: GitHub.