rohitg00/ai-engineering-from-scratch · error · ValueError
release gate root must be an object
Error message
release gate root must be an object
What it means
Raised in load_release_gate when the parsed release-gate JSON's root is not an object. The gate validator reads keyed members (severeCasePassRate, severeCases, evaluationSurfaces, trace fields), so a non-object root means the gate file is structurally invalid and validation cannot proceed.
Solutions
- Fix the release-gate JSON so its root is an object with the required keyed sections
- Regenerate the gate file from the eval harness instead of hand-editing
- Catch ValueError in the tests to assert the gate fixture fails structurally when corrupted
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at certifications/claude/lessons/14-evals-testing-debugging-and-observability/code/main.py:133 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/0122c0878ac28f3c.
Report an issue: GitHub.
Appendix: source
Thrown at certifications/claude/lessons/14-evals-testing-debugging-and-observability/code/main.py:133
errors.append("severeCasePassRate must be 1.0")
if not isinstance(gate.get("severeCases"), list) or len(gate["severeCases"]) < 3:
errors.append("at least three severeCases are required")
required_surfaces = {"output", "trajectory", "final-state", "safety", "operational-budget"}
if not required_surfaces <= set(gate.get("evaluationSurfaces", [])):
errors.append("all five evaluation surfaces are required")
required_trace = {"trace_id", "type", "model_version", "prompt_version", "policy", "latency_ms", "result_class"}
if not required_trace <= set(gate.get("requiredTraceFields", [])):
errors.append("required trace fields are incomplete")
required_failures = {"transport_timeout", "protocol_error", "contract_parse_error", "policy_denial", "final_state_failure"}
if not required_failures <= set(gate.get("failureClasses", [])):
errors.append("failure classes are incomplete")
return errors
def load_release_gate(path: str) -> dict[str, Any]:
value = json.loads(Path(path).read_text(encoding="utf-8"))
if not isinstance(value, dict):
raise ValueError("release gate root must be an object")
return value
def _elapsed_ms(started: float) -> float:
return (time.perf_counter() - started) * 1000
def demo_agent(prompt: str) -> AgentRun:
if "missing" in prompt:
return AgentRun("I cannot verify that order.", (), {"escalated": True}, ({"type": "decision", "reason": "missing_id"},))
return AgentRun("Order A-17 is ready.", ("lookup_order",), {"escalated": False}, ({"type": "tool_call", "name": "lookup_order"},))
def demo() -> dict[str, Any]:
cases = [
EvalCase("known", "Find A-17", ("ready",), (), ("lookup_order",), {"escalated": False}),
EvalCase("missing", "The order id is missing", ("cannot verify",), ("ready",), (), {"escalated": True}),
]View on GitHub (pinned to 39ea8a1c6d)