affaan-m/ECC · error · ContractError
artifact has invalid reference SHA-256
Error message
artifact {relative} has invalid reference SHA-256 What it means
Each provenance source must include a 'reference_sha256' that is a string of exactly 64 hex characters (a SHA-256 digest). This error is raised when the digest is missing, non-string, or the wrong length. It lets the validator match the cited source against the set of known reference files.
Solutions
- Recompute the reference file digest with hashlib.sha256(...).hexdigest() and store the full 64-char string
- Verify no truncation or surrounding whitespace/prefix when pasting the hash
- Regenerate the receipt through tasteforge so digests are computed correctly
- Ensure the reference file itself still hashes to the recorded digest before validation
Example fix
import hashlib
# before
'reference_sha256': '3f2a1b' # truncated
# after
'reference_sha256': hashlib.sha256(Path('refs/intro.mp4').read_bytes()).hexdigest() Defensive patterns
Strategy: validation
Validate before calling
import re
d = src.get('reference_sha256')
assert isinstance(d, str) and re.fullmatch(r'[0-9a-f]{64}', d), f'bad digest: {d!r}' Type guard
def valid_sha256(value) -> bool:
return isinstance(value, str) and len(value) == 64 and all(c in '0123456789abcdef' for c in value) Try / catch
try:
validate_artifact_receipt(out_dir)
except ContractError as e:
if 'invalid reference SHA-256' in str(e):
recompute_reference_digests(receipt)
else:
raise Prevention
- Always hash with hashlib.sha256().hexdigest(), never md5/sha1
- Paste full 64-char digests; never abbreviate
- Recompute digests whenever a reference file changes
- Add digest-format linting to receipt tooling
When it happens
Trigger: A provenance source whose reference_sha256 is absent, truncated (e.g. short hash), a full hash with 0x prefix, a non-string type, or computed with a different algorithm (MD5/SHA-1) producing the wrong length.
Common situations: Hand-editing receipts with abbreviated hashes; hashing with md5() instead of sha256(); copying hashes from other tooling formats; older receipts generated before 64-char digests were enforced.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- anchor evidence source duration is not bound to its receipt…
- rule lacks immutable reference evidence
- a generated candidate cannot claim original-source identity
- 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/19710a89627c53f3.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:414
if not isinstance(entry.get("genre_numbers"), list):
raise ContractError(f"artifact {relative} lacks genre binding")
modalities = entry.get("modalities")
if (not isinstance(modalities, list)
or any(modality not in _REQUIRED_MODALITIES for modality in modalities)):
raise ContractError(f"artifact {relative} has invalid modality binding")
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",View on GitHub (pinned to 8321021c54)