affaan-m/ECC · error · ContractError
lacks probe evidence
Error message
{label} lacks probe evidence What it means
_validate_probe_evidence requires the probe field of an artifact receipt to be a dict (object). If probe is missing, null, or any non-object type, the validator raises 'lacks probe evidence' because media claims must be backed by structured probe data (duration, sample_times, scene_changes, style_samples).
Solutions
- Add a complete probe object to the receipt (duration, sample_times, scene_changes, style_samples).
- Re-run the media probe step so the receipt is regenerated with its evidence attached.
- Restore the probe section if a post-processing step stripped it from the receipt.
- Upgrade/regenerate receipts produced by an older tool version with a different schema.
Example fix
// before
{"artifact": "a.png", "probe": null}
// after
{"artifact": "a.png", "probe": {"duration": 12.5, "sample_times": [0.0, 6.25], "scene_changes": [], "style_samples": []}} Defensive patterns
Strategy: type-guard
Validate before calling
def probe_present(receipt) -> bool:
return isinstance(receipt, dict) and isinstance(receipt.get('probe'), dict) Type guard
def has_probe(obj) -> bool:
return isinstance(obj, dict) and isinstance(obj.get('probe'), dict) Try / catch
try:
validate_artifact_receipt(receipt)
except ContractError as e:
if 'lacks probe evidence' in str(e):
receipt['probe'] = run_media_probe(receipt['artifact'])
else:
raise Prevention
- Never strip the probe section from receipts to save space
- Regenerate receipts after schema upgrades rather than patching them
- Keep probe generation as a mandatory step in the receipt pipeline
- Validate receipts against the full schema before distribution
When it happens
Trigger: validate_artifact_receipt called on a receipt whose 'probe' key is absent, explicitly null, or set to a string/list instead of an object.
Common situations: Receipts stripped of the probe section to shrink file size, older receipt formats with a flat probe schema, hand-authored receipts that forgot the probe block, or a merge that dropped the key.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- input_artifacts must be a list
- interview produced an invalid profile
- Invalid provenance metadata
- has invalid
- probe duration is not bound to source duration
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5978c3e6e389457e.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:53
def _validate_numeric_evidence(value: Any, *, label: str) -> None:
if isinstance(value, bool):
raise ContractError(f"{label} contains a boolean numeric value")
if isinstance(value, (int, float)):
if not math.isfinite(value):
raise ContractError(f"{label} contains a non-finite numeric value")
elif isinstance(value, dict):
for nested in value.values():
_validate_numeric_evidence(nested, label=label)
elif isinstance(value, list):
for nested in value:
_validate_numeric_evidence(nested, label=label)
def _validate_probe_evidence(probe: Any, source_duration: float, *, label: str) -> None:
if not isinstance(probe, dict):
raise ContractError(f"{label} lacks probe evidence")
_validate_numeric_evidence(probe, label=label)
if probe.get("duration") != source_duration:
raise ContractError(f"{label} probe duration is not bound to source duration")
for field in ("sample_times", "scene_changes"):
values = probe.get(field, [])
if not isinstance(values, list):
raise ContractError(f"{label} has invalid {field}")
for value in values:
_validate_media_time(value, source_duration, label=f"{label} {field}")
samples = probe.get("style_samples", [])
if not isinstance(samples, list) or any(not isinstance(sample, dict) for sample in samples):
raise ContractError(f"{label} has invalid style evidence")
for sample in samples:
_validate_media_time(sample.get("time"), source_duration, label=f"{label} style evidence")
def _sha256(path: Path) -> str:
if not hasattr(os, "O_NOFOLLOW"):View on GitHub (pinned to 8321021c54)