affaan-m/ECC · error · ContractError
receipt must declare an explicit source availability policy
Error message
receipt must declare an explicit source availability policy
What it means
When a receipt declares any provenance sources (references or evidence_files are non-empty), it must also set "source_availability_policy" to exactly "allow_unavailable" or "require_available". If sources exist and the policy is missing or any other value, ContractError('receipt must declare an explicit source availability policy') is raised, forcing an explicit decision about how missing sources are handled.
Solutions
- Add "source_availability_policy": "require_available" (fail when sources are missing) or "allow_unavailable" (skip missing sources) to the receipt
- Correct the spelling/casing to one of the two exact allowed strings
- Regenerate the receipt with current tasteforge tooling so the field is emitted
Example fix
// before
{"references": [...]} // no policy
// after
{"references": [...], "source_availability_policy": "require_available"} Defensive patterns
Strategy: validation
Validate before calling
POLICIES = {'allow_unavailable', 'require_available'}
def policy_ok(receipt):
has_sources = bool(receipt.get('references')) or bool(receipt.get('evidence_files'))
return not has_sources or receipt.get('source_availability_policy') in POLICIES Type guard
def declares_policy(receipt) -> bool:
return receipt.get('source_availability_policy') in {'allow_unavailable', 'require_available'} Try / catch
try:
validate_artifact_receipt(receipt, out_dir)
except ContractError as e:
if 'source availability policy' in str(e):
receipt['source_availability_policy'] = 'require_available'
validate_artifact_receipt(receipt, out_dir)
raise Prevention
- Always set source_availability_policy when emitting sources
- Use require_available for reproducible bundles; allow_unavailable only intentionally
- Copy the exact strings — no hyphens or different casing
- Add the policy field to your receipt JSON schema as an enum
When it happens
Trigger: A receipt listing references/evidence_files but omitting "source_availability_policy"; the key set to null, "", or a typo like "allow-unavailable"/"RequireAvailable"; sources added to an older receipt that never carried the policy field.
Common situations: Upgrading receipts from an older tasteforge format without the policy field; typos or casing mistakes in the policy string; template-generated receipts that only set the policy conditionally.
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
- application config exceeds local size limit
- artifact path must be a non-empty relative path
- artifact byte size does not match receipt
- artifact has invalid modality binding
- artifact has invalid reference path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/53685040c803e767.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:344
if (not isinstance(source_path, str) or not source_path
or not isinstance(expected_digest, str)
or not re.fullmatch(r"[0-9a-f]{64}", expected_digest)):
raise ContractError("receipt has an invalid source identity")
known_sources.add((source_path, expected_digest))
if key == "references":
source_duration = source.get("source_duration")
if not _is_finite_real(source_duration):
raise ContractError("receipt reference has an invalid finite source duration")
source_duration = cast(float, source_duration)
if float(source_duration) <= 0:
raise ContractError("receipt reference has an invalid finite source duration")
source_durations[(source_path, expected_digest)] = float(source_duration)
_validate_probe_evidence(
source.get("probe"), float(source_duration), label="receipt reference"
)
source_policy = receipt.get("source_availability_policy")
if known_sources and source_policy not in {"allow_unavailable", "require_available"}:
raise ContractError("receipt must declare an explicit source availability policy")
for source_path, expected_digest in sorted(known_sources):
path = Path(source_path)
try:
metadata = path.lstat()
except FileNotFoundError:
if source_policy == "require_available":
raise ContractError(f"receipt source is unavailable: {source_path}") from None
continue
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISREG(metadata.st_mode):
raise ContractError(f"receipt source is not a safe regular file: {source_path}")
try:
actual_digest = _sha256(path)
except FileNotFoundError:
if source_policy == "require_available":
raise ContractError(f"receipt source is unavailable: {source_path}") from None
continue
except OSError:
raise ContractError(f"receipt source cannot be securely read: {source_path}") from NoneView on GitHub (pinned to 8321021c54)