{"record":{"id":"d676a1b19b0db4da","repo":"abhigyanpatwari/GitNexus","slug":"task-binding-count-does-not-match-selected-tasks","errorCode":null,"errorMessage":"task binding count does not match selected tasks","messagePattern":"task binding count does not match selected tasks","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/runner_tasks.py","lineNumber":109,"sourceCode":"        \"expensive\": bool(task.get(\"expensive\", False)),\n        \"sandbox_copy\": list(task.get(\"sandbox_copy\", [])),\n        \"sandbox_dependencies\": [dict(item) for item in task.get(\"sandbox_dependencies\", [])],\n        **dependency_binding,\n        **oracle_snapshot.binding,\n    }\n\n\ndef resolve_task_bindings(\n    tasks: list[dict[str, Any]],\n    expected: list[dict[str, Any]] | None = None,\n    *,\n    oracle_snapshots: list[TaskOracleSnapshot] | None = None,\n    task_asset_cache: TaskAssetCache | None = None,\n) -> list[dict[str, Any]]:\n    \"\"\"Resolve each repo/ref once and optionally honor an upstream immutable pin.\"\"\"\n\n    if expected is not None and len(expected) != len(tasks):\n        raise ValueError(\"task binding count does not match selected tasks\")\n    snapshots = oracle_snapshots if oracle_snapshots is not None else capture_task_oracles(tasks)\n    if len(snapshots) != len(tasks):\n        raise ValueError(\"oracle snapshot count does not match selected tasks\")\n    bindings: list[dict[str, Any]] = []\n    for index, (task, oracle_snapshot) in enumerate(zip(tasks, snapshots, strict=True)):\n        requested_repo = Path(task[\"repo\"]).expanduser().resolve()\n        repo_output = run_checked(\n            [\"git\", \"-C\", str(requested_repo), \"rev-parse\", \"--show-toplevel\"],\n            timeout=60,\n        ).stdout_tail.strip()\n        repo_identity = Path(repo_output).resolve()\n        if expected is None:\n            resolved_sha = run_checked(\n                [\n                    \"git\",\n                    \"-C\",\n                    str(repo_identity),\n                    \"rev-parse\",","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/runner_tasks.py#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"Editing the tasks file after caching bindings; CI replaying a stale bindings artifact against a newer tasks file.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"expected = json.load(open(\"bindings.json\")) if path else None\nif expected is not None and len(expected) != len(tasks):\n    raise SystemExit(\"regenerate bindings: task count changed\")","typeGuard":"def binding_count_matches(tasks: list, expected: list | None) -> bool:\n    return expected is None or len(expected) == len(tasks)","tryCatchPattern":null,"preventionTips":["Regenerate the bindings JSON whenever the task list changes.","Commit tasks and bindings together so they stay aligned."],"tags":["workflow-bench","task-binding","pinning","reproducibility"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}