affaan-m/ECC · error · ContractError

has invalid style evidence

Error message

{label} has invalid style evidence

What it means

This error is raised by _validate_probe_evidence in the tasteforge contract module when a probe's 'style_samples' field is malformed. The library requires style_samples to be a list of dictionaries (style evidence objects). It throws to enforce the probe contract before receipt validation proceeds, ensuring downstream style-transfer logic only ever sees well-formed evidence.

Solutions

  1. Inspect the probe's style_samples field and make it a list of dicts: [{"time": <number>, ...}, ...]
  2. Regenerate the probe/receipt with the current tasteforge script version instead of hand-editing
  3. Validate the JSON with a schema checker before calling validate_artifact_receipt
  4. If migrating from an older format, rename/remap the old style-evidence key to style_samples

Example fix

// before
probe = {"style_samples": "clip1@0.5, clip2@2.0"}
// after
probe = {"style_samples": [{"time": 0.5}, {"time": 2.0}]}
Defensive patterns

Strategy: validation

Validate before calling

samples = probe.get("style_samples", [])
if not isinstance(samples, list) or any(not isinstance(s, dict) for s in samples):
    raise ValueError(f"{label}: style_samples must be a list of dicts")

Type guard

def is_style_samples(v) -> bool:
    return isinstance(v, list) and all(isinstance(s, dict) for s in v)

Try / catch

try:
    validate_artifact_receipt(bundle_root)
except ContractError as e:
    if 'invalid style evidence' in str(e):
        print(f'Fix probe style_samples shape: {e}')
    else:
        raise

Prevention

When it happens

Trigger: Calling validate_artifact_receipt with a receipt whose probe object has style_samples that is not a list (e.g. a dict, string, or null), or a list containing non-dict entries (strings, numbers, nested lists).

Common situations: Hand-edited receipts, receipts generated by older script versions that stored style samples in a different shape, JSON round-trips that turned tuples into something unexpected, or probes copied from a different tool's output format.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/5ae396c9f11bf456. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/contract.py:65

        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"):
        raise ContractError("secure receipt validation requires O_NOFOLLOW")
    descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
    digest = hashlib.sha256()
    try:
        metadata = os.fstat(descriptor)
        if not stat.S_ISREG(metadata.st_mode):
            raise ContractError(f"receipt source is not a regular file: {path}")
        while True:
            chunk = os.read(descriptor, 1024 * 1024)
            if not chunk:
                break
            digest.update(chunk)

View on GitHub (pinned to 8321021c54)