affaan-m/ECC · error · ContractError
artifact has invalid reference/time provenance
Error message
artifact {relative} has invalid reference/time provenance What it means
Each provenance source must declare a 'time_basis' of exactly 'media_seconds' or 'whole_file', and 'reference_times' must be a list. This error is raised when times is not a list or the basis is missing/outside the allowed set. The validator uses this to know how the artifact's use of the reference is temporally bound.
Solutions
- Set time_basis to exactly 'media_seconds' (time-ranged usage) or 'whole_file' (full reference usage)
- Change reference_times to a list (possibly empty for whole_file)
- Regenerate the receipt via tasteforge to emit canonical field values
- Check for typos — the accepted set is exactly {'media_seconds','whole_file'}
Example fix
# before
{'reference_path': 'refs/a.mp4', 'time_basis': 'full', 'reference_times': None}
# after
{'reference_path': 'refs/a.mp4', 'time_basis': 'whole_file', 'reference_times': []} Defensive patterns
Strategy: validation
Validate before calling
VALID_BASES = {'media_seconds', 'whole_file'}
for src in entry['provenance']:
assert isinstance(src.get('reference_times'), list), 'reference_times must be a list'
assert src.get('time_basis') in VALID_BASES, f'bad time_basis: {src.get("time_basis")!r}' Type guard
def valid_time_provenance(src: dict) -> bool:
return (isinstance(src.get('reference_times'), list)
and src.get('time_basis') in {'media_seconds', 'whole_file'}) Try / catch
try:
validate_artifact_receipt(out_dir)
except ContractError as e:
if 'invalid reference/time provenance' in str(e):
normalize_time_fields(receipt)
else:
raise Prevention
- Use only the two documented basis strings verbatim
- Model provenance with a dataclass/TypedDict so invalid values cannot be constructed
- Replace None with [] for reference_times at generation time
- Diff receipts against a schema after migrations
When it happens
Trigger: A provenance source with time_basis values like 'seconds', 'full', 'media', or null; reference_times set to null, a dict, or a string; omitting one of the two fields entirely.
Common situations: Hand-written receipts inventing their own basis names, schema migrations changing field names, generators emitting null for times when they meant [], and typos such as 'media_second'.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- artifact whole-file provenance must not invent times
- a generated candidate cannot claim original-source identity
- anchor evidence source duration is not bound to its receipt…
- artifact cites an unknown provenance source
- artifact has an unbound source duration
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/c5bccbbf333c12d7.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:420
if entry.get("bytes") != path.stat().st_size:
raise ContractError(f"artifact {relative} byte size does not match receipt")
if entry.get("sha256") != _sha256(path):
raise ContractError(f"artifact {relative} SHA-256 does not match receipt")
provenance = entry.get("provenance")
if not isinstance(provenance, list) or not provenance:
raise ContractError(f"artifact {relative} lacks exact reference/time provenance")
for source in provenance:
if not isinstance(source.get("reference_path"), str) or not source["reference_path"]:
raise ContractError(f"artifact {relative} has invalid reference path")
digest = source.get("reference_sha256")
if not isinstance(digest, str) or len(digest) != 64:
raise ContractError(f"artifact {relative} has invalid reference SHA-256")
if (source["reference_path"], digest) not in known_sources:
raise ContractError(f"artifact {relative} cites an unknown provenance source")
times = source.get("reference_times")
basis = source.get("time_basis")
if not isinstance(times, list) or basis not in {"media_seconds", "whole_file"}:
raise ContractError(f"artifact {relative} has invalid reference/time provenance")
if basis == "media_seconds" and not times:
raise ContractError(f"artifact {relative} lacks media reference times")
if basis == "whole_file" and times:
raise ContractError(f"artifact {relative} whole-file provenance must not invent times")
if basis == "media_seconds":
expected_duration = source_durations.get((source["reference_path"], digest))
if expected_duration is None or source.get("source_duration") != expected_duration:
raise ContractError(f"artifact {relative} has an unbound source duration")
for time in times:
_validate_media_time(
time, expected_duration,
label=f"artifact {relative} media reference time",
)
digest_payload = dict(receipt)
claimed_digest = digest_payload.pop("receipt_sha256", None)
actual_digest = hashlib.sha256(
json.dumps(digest_payload, sort_keys=True, separators=(",", ":")).encode("utf-8")View on GitHub (pinned to 8321021c54)