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

  1. Add a complete probe object to the receipt (duration, sample_times, scene_changes, style_samples).
  2. Re-run the media probe step so the receipt is regenerated with its evidence attached.
  3. Restore the probe section if a post-processing step stripped it from the receipt.
  4. 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

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


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)