affaan-m/ECC · error · ContractError
artifact lacks media reference times
Error message
artifact {relative} lacks media reference times What it means
When a provenance source declares time_basis 'media_seconds', its reference_times list must be non-empty — citing specific media timestamps is the whole point of that basis. This error is raised when the times list is empty or missing for a media_seconds source.
Solutions
- Populate reference_times with the actual media timestamps (in seconds) the artifact derives from
- If the artifact uses the entire reference, change time_basis to 'whole_file' and keep times empty instead
- Regenerate the artifact through the pipeline so times are captured automatically
- Validate each timestamp is within the source duration to also avoid downstream media-time errors
Example fix
# before
{'time_basis': 'media_seconds', 'reference_times': []}
# after
{'time_basis': 'media_seconds', 'reference_times': [12.5, 30.0]} Defensive patterns
Strategy: validation
Validate before calling
if src.get('time_basis') == 'media_seconds':
times = src.get('reference_times')
assert isinstance(times, list) and len(times) > 0, 'media_seconds requires non-empty reference_times' Type guard
def has_media_times(src: dict) -> bool:
return src.get('time_basis') != 'media_seconds' or bool(src.get('reference_times')) Try / catch
try:
validate_artifact_receipt(out_dir)
except ContractError as e:
if 'lacks media reference times' in str(e):
capture_timestamps_or_switch_to_whole_file(src)
else:
raise Prevention
- Capture timestamps at generation time, not during hand-authoring
- Default to whole_file when no time range is meaningful
- Validate times are within the source duration before receipt signing
- Never copy whole_file templates into media_seconds entries without adding times
When it happens
Trigger: A source with time_basis='media_seconds' and reference_times=[] (or the key omitted); switching a whole_file source to media_seconds without adding timestamps.
Common situations: Template receipts copied from a whole_file example, generators that fail to capture timestamps for time-ranged edits, developers switching basis values without updating the times list.
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
- 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
- artifact has invalid reference path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/c2fb74ac5bace063.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:422
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")
).hexdigest()
if claimed_digest != actual_digest:View on GitHub (pinned to 8321021c54)