mvanhorn/last30days-skill · error · ValueError
missing required field '{field}'
Error message
missing required field '{field}' What it means
Required-field check in validate_external_plan: the top-level object must contain the four keys 'intent', 'freshness_mode', 'cluster_mode', and 'subqueries'. The first missing one is reported by name. These fields are the minimum skeleton the sanitizer needs to canonicalize a plan; enum values themselves are checked permissively later, but presence is mandatory.
Source
Thrown at skills/last30days/scripts/lib/planner.py:173
"github": {"discussion", "link"},
"grounding": {"web", "reference", "link"},
"perplexity": {"web", "reference", "analysis"},
"jobs": {"jobs", "company_signal", "link"},
"corpus": {"reference", "analysis"},
}
def validate_external_plan(raw: dict) -> None:
"""Validate explicit-plan structure before permissive sanitization.
Enum-like metadata stays permissive because direct pipeline callers rely on
the sanitizer to canonicalize those values.
"""
if not isinstance(raw, dict):
raise ValueError("top-level plan must be an object")
for field in ("intent", "freshness_mode", "cluster_mode", "subqueries"):
if field not in raw:
raise ValueError(f"missing required field '{field}'")
for field in ("intent", "freshness_mode", "cluster_mode"):
if not isinstance(raw[field], str) or not raw[field].strip():
raise ValueError(f"field '{field}' must be a non-empty string")
source_weights = raw.get("source_weights")
if source_weights is not None and not isinstance(source_weights, dict):
raise ValueError("field 'source_weights' must be an object when provided")
for source, weight in (source_weights or {}).items():
if (
not isinstance(source, str)
or not source.strip()
or isinstance(weight, bool)
or not isinstance(weight, (int, float))
):
raise ValueError("field 'source_weights' must map source names to numbers")
subqueries = raw["subqueries"]
if not isinstance(subqueries, list) or not subqueries:
raise ValueError("field 'subqueries' must be a non-empty array")View on GitHub (pinned to c7460f6114)
Solutions
- Add the missing field named in the message — e.g. "freshness_mode": "recent" and "cluster_mode": "thematic".
- Start from a plan produced by the planner itself (serialize a generated plan) and edit it, so all required fields are present.
- Keep a schema checklist: intent, freshness_mode, cluster_mode, subqueries.
Example fix
# before
plan = {"intent": "factual", "freshness_mode": "recent", "subqueries": [...]}
# after
plan = {"intent": "factual", "freshness_mode": "recent", "cluster_mode": "thematic", "subqueries": [...]} Defensive patterns
Strategy: validation
Validate before calling
REQUIRED = ("intent", "freshness_mode", "cluster_mode", "subqueries")
missing = [f for f in REQUIRED if f not in plan]
if missing:
raise SystemExit(f"plan missing fields: {missing}") Type guard
def has_required_plan_fields(plan: dict) -> bool:
return isinstance(plan, dict) and all(f in plan for f in ("intent", "freshness_mode", "cluster_mode", "subqueries")) Try / catch
try:
planner.validate_external_plan(plan)
except ValueError as exc:
if "missing required field" in str(exc):
field = str(exc).split("'")[1]
plan.setdefault(field, DEFAULTS[field])
planner.validate_external_plan(plan)
else:
raise Prevention
- Keep a DEFAULTS dict for the four required fields and setdefault each before submission.
- Generate plans from the planner itself and edit from that template.
When it happens
Trigger: Passing an external plan dict that omits any of the four fields — e.g. only {'intent': 'factual', 'subqueries': [...]} missing freshness_mode/cluster_mode.
Common situations: Hand-authored plan JSON missing a metadata field; an LLM-generated plan that skipped cluster_mode; older plan schemas from previous versions that lacked one of the fields; trimming a plan template too aggressively.
Related errors
- top-level plan must be an object
- field '{field}' must be a non-empty string
- field 'source_weights' must be an object when provided
- field 'source_weights' must map source names to numbers
- field 'subqueries' must be a non-empty array
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/fcdd4e9809fcbd6c.
Report an issue: GitHub.