mvanhorn/last30days-skill · error · HandoffContractError
Judgments file {path} must carry a top-level \"judgments\" l
Error message
Judgments file {path} must carry a top-level \"judgments\" list. What it means
Raised by the judgments loader in discovery_handoff.py when the file is valid JSON, is a top-level object, and is correctly bundle-bound, but the 'judgments' key is missing or is not a JSON list. This is the third strictness tier: strict on top-level structure, lenient per row (unknown ids are warned, junk fields degrade per-row). It is a HandoffContractError, so the fix is always on the host-file side.
Source
Thrown at skills/last30days/scripts/lib/discovery_handoff.py:764
save_dir: str | Path | None = None,
config_dir: Path | None = None,
) -> dict[str, HostJudgment]:
"""Read the host judgments file for leg 2, keyed by nomination id.
Strict at the top level (readable, valid JSON object, ``judgments`` list,
bundle_id bound to ``bundle``), lenient per row: an unknown id is warned
and ignored, a missing/unusable name or junk field is per-row-absent, and
worthiness is clamped to 0-100 integers. Nominations with no row at all
are simply missing from the mapping - use ``judgment_for`` to get the
ROW_ABSENT marker for them.
"""
payload = _load_host_file(path, "judgments")
_require_bundle_binding(
payload, bundle, label="judgments", save_dir=save_dir, config_dir=config_dir,
)
rows = payload.get("judgments")
if not isinstance(rows, list):
raise HandoffContractError(
f"Judgments file {path} must carry a top-level \"judgments\" list."
)
known = {entry.nomination_id for entry in bundle.nominations}
judgments: dict[str, HostJudgment] = {}
for row_id, row in _known_rows(
rows, known, row_label="judgments", unknown_label="judgment"
):
# Only a real JSON boolean is a junk verdict: null, "false", 0, or
# any other non-bool value is per-row-absent (bundle heuristic),
# never coerced - bool("false") is True.
raw_junk = row.get("junk")
judgments[row_id] = HostJudgment(
name=_sanitized_name(row.get("name")),
junk=raw_junk if isinstance(raw_junk, bool) else None,
worthiness=_clamped_worthiness(row.get("worthiness")),
)
return judgments
View on GitHub (pinned to c7460f6114)
Solutions
- Ensure the top-level object contains "judgments": [...] — a JSON array of row objects, each with nomination_id.
- Check spelling and case exactly: the key must be lowercase 'judgments'.
- After fixing, re-run the same leg; per-row problems will not raise this error, only the missing/mistyped key does.
Example fix
// before
{
"bundle_id": "...",
"rows": [{"nomination_id": "n1", "junk": false}]
}
// after
{
"bundle_id": "...",
"judgments": [{"nomination_id": "n1", "junk": false}]
} Defensive patterns
Strategy: validation
Validate before calling
import json
def valid_judgments_file(path: str) -> bool:
payload = json.loads(open(path, encoding="utf-8").read())
return isinstance(payload, dict) and isinstance(payload.get("judgments"), list) Try / catch
try:
load_judgments(path, bundle, ...)
except HandoffContractError as e:
if 'top-level' in str(e) and 'judgments' in str(e):
# structural fix on host side: add/rename the "judgments" array key
... Prevention
- Generate the file from a dict literal: {"bundle_id": ..., "judgments": rows} — the key name cannot drift.
- Do not paraphrase schema keys; copy them verbatim from the docs.
- Per-row leniency means only top-level shape raises — focus review on the wrapper, not each row.
When it happens
Trigger: Passing a judgments file whose top-level object omits the 'judgments' key entirely; naming the key differently ('rows', 'entries', 'items'); setting "judgments": {...} (an object) instead of an array; setting it to null.
Common situations: The host model paraphrases the schema and renames the key; a partially written file from an interrupted edit; copy-pasting an angles-file shape for a judgments file.
Related errors
- Angles file {path} must carry a top-level \"angles\" list.
- {label.capitalize()} file {file_path} must be a top-level JS
- {repo_dir.name} emitted the agent JSON profile; the evaluato
- [CompetitorsPlan] Top-level must be a dict of {entity: {targ
- {label} {path} must be a top-level JSON object, got {type(pa
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/ef5731a48fa9c115.
Report an issue: GitHub.