abhigyanpatwari/GitNexus · error · ValueError

task binding {index} must be an object

Error message

task binding {index} must be an object

What it means

Raised by resolve_task_bindings when an `expected` pin entry is not a dict (runner_tasks.py:133-135). Each pin must be an object carrying at least resolved_sha and the definition fields; a non-object entry (string, number, null, list) is rejected before any field is read.

Source

Thrown at eval/workflow_bench/runner_tasks.py:135

            ["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",
                    f"{task.get('ref', 'HEAD')}^{{commit}}",
                ],
                timeout=60,
            ).stdout_tail.strip()
        else:
            supplied = expected[index]
            if not isinstance(supplied, dict):
                raise ValueError(f"task binding {index} must be an object")
            resolved_sha = str(supplied.get("resolved_sha", ""))
        if not re.fullmatch(r"[0-9a-fA-F]{40,64}", resolved_sha):
            raise ValueError(f"task {task['id']} did not resolve to an immutable commit")
        exists = run_managed(
            ["git", "-C", str(repo_identity), "cat-file", "-e", f"{resolved_sha}^{{commit}}"],
            timeout=60,
        )
        if not exists.ok:
            raise ValueError(f"pinned task commit is unavailable for {task['id']}: {resolved_sha}")
        if task_asset_cache is None:
            dependency_binding = capture_task_dependency_binding(
                task,
                repo=repo_identity,
                resolved_sha=resolved_sha.lower(),
            )
        else:
            dependency_binding = task_asset_cache.prepare(
                task,

View on GitHub (pinned to d540b00184)

Solutions

  1. Inspect the bindings JSON: every element must be a JSON object.
  2. Regenerate the bindings file rather than editing it by hand.
  3. Validate with `jq 'map(type == "object") | all' bindings.json`.

Example fix

// before: ["abc123...", {"id":"t2",...}]
// after:  [{"id":"t1","resolved_sha":"abc123...",...}, {"id":"t2",...}]
Defensive patterns

Strategy: type-guard

Validate before calling

expected = json.load(open("bindings.json"))
for i, entry in enumerate(expected):
    if not isinstance(entry, dict):
        raise SystemExit(f"bindings[{i}] must be an object")

Type guard

def all_bindings_are_objects(expected: list) -> bool:
    return all(isinstance(e, dict) for e in expected)

Prevention

When it happens

Trigger: The --task-bindings-json file contains a top-level list but one element is a bare string SHA or null; a hand-edited pin file with a malformed row.

Common situations: Truncating or hand-editing the bindings JSON; a serialization bug that emits scalars.

Related errors


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