affaan-m/ECC · error · ValueError
Missing required field {e} at line {i}
Error message
Missing required field {e} at line {i} What it means
Each JSONL observation record must contain the keys timestamp, event, tool, and session (input and output default to ''). When one is missing, the ObservationEvent construction raises KeyError, which is wrapped as ValueError naming the missing field and the line number.
Source
Thrown at skills/skill-comply/scripts/parser.py:72
return []
events: list[ObservationEvent] = []
for i, line in enumerate(text.splitlines(), 1):
try:
raw = json.loads(line)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON at line {i}: {e}") from e
try:
events.append(ObservationEvent(
timestamp=raw["timestamp"],
event=raw["event"],
tool=raw["tool"],
session=raw["session"],
input=raw.get("input", ""),
output=raw.get("output", ""),
))
except KeyError as e:
raise ValueError(f"Missing required field {e} at line {i}") from e
return sorted(events, key=lambda e: e.timestamp)
def parse_spec(path: Path) -> ComplianceSpec:
"""Parse a YAML compliance spec file."""
if not path.is_file():
raise FileNotFoundError(f"Spec file not found: {path}")
raw = yaml.safe_load(path.read_text())
steps: list[Step] = []
for s in raw["steps"]:
d = s["detector"]
steps.append(Step(
id=s["id"],
description=s["description"],
required=s["required"],
detector=Detector(View on GitHub (pinned to 01e15490f0)
Solutions
- Inspect the named field and line number in the message and fix the source record.
- If the producer uses different key names, normalize records before write (alias session_id -> session).
- Run a small jsonschema check over the first record of the trace to catch schema drift early.
- Regenerate the trace from runner.run_scenario so it matches the parser's expected schema.
Example fix
# before (producer emits session_id)
# {"timestamp":"T0001","event":"tool_complete","tool":"Read","session_id":"abc"}
# after (normalize before writing the JSONL)
record = {"timestamp": ts, "event": ev, "tool": tool, "session": sid, "input": inp, "output": out}
fout.write(json.dumps(record) + '\n') Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
REQUIRED = {'timestamp', 'event', 'tool', 'session'}
def validate_trace_schema(path: Path) -> list[tuple[int, set[str]]]:
missing: list[tuple[int, set[str]]] = []
for i, line in enumerate(path.read_text().splitlines(), 1):
line = line.strip()
if not line:
continue
keys = set(json.loads(line))
gap = REQUIRED - keys
if gap:
missing.append((i, gap))
return missing Try / catch
from scripts.parser import parse_trace
try:
events = parse_trace(path)
except ValueError as e:
if 'Missing required field' in str(e):
# identify and drop/repair the offending record
raise Prevention
- Keep the trace producer and parser schemas in a single shared constant or pydantic model.
- Write a contract test that runs parse_trace over a known-good fixture on every CI run.
- When aliasing keys (session_id -> session), do it at write time, not read time.
When it happens
Trigger: A trace producer omits one of the required keys; a renamed field (e.g. 'session_id' instead of 'session') reaches the parser; a manually edited trace line drops a key.
Common situations: An upstream schema change in the stream-json adapter (_parse_stream_json) that emits a different key name; third-party tools writing a 'compatible' JSONL with subtly different field names.
Related errors
- Trace file not found: {path}
- Invalid JSON at line {i}: {e}
- Missing 'scoring' section in compliance spec
- Invalid install-state (${label}): ${details}
- Install module ${moduleId} has invalid targets; expected an
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/9a490c214563a2d8.
Report an issue: GitHub.