affaan-m/ECC · error · ValueError
Unsupported asset receipt schema
Error message
Unsupported asset receipt schema
What it means
validate_assets checks that the receipt's 'schema' field equals the supported schema constant 'tasteforge.assets.v1'. Any other or missing schema value is rejected, since validation semantics (required fields, hashing rules) are version-specific. This guards against validating foreign or newer-format receipts.
Solutions
- Pass the asset receipt produced by ingest_assets (schema 'tasteforge.assets.v1'), not a bundle receipt or arbitrary JSON.
- Check receipt['schema'] before calling validate_assets.
- If receipts are from an older tasteforge schema, re-ingest with the current version to produce a v1 receipt; there is no migration path in this code.
- Fix typos if the schema string was hand-crafted.
Example fix
# before
validate_assets('bundle/receipt.json') # bundle schema, not assets schema
# after
validate_assets('out/assets-receipt.json') # produced by ingest_assets Defensive patterns
Strategy: type-guard
Validate before calling
import json
receipt = json.loads(open(p).read())
assert receipt.get('schema') == 'tasteforge.assets.v1', 'not a tasteforge asset receipt' Type guard
def is_asset_receipt(obj) -> bool:
return isinstance(obj, dict) and obj.get('schema') == 'tasteforge.assets.v1' Prevention
- Only validate receipts produced by ingest_assets.
- Distinguish bundle receipts from asset receipts in your pipeline layout.
- Track schema versions when upgrading the tool and re-ingest old receipts.
When it happens
Trigger: Calling validate_assets on a JSON file that is not a tasteforge asset receipt (missing 'schema'); a receipt produced by a different tool or a newer/older tasteforge schema version; hand-built receipts with a wrong schema string; passing a bundle receipt.json (different schema) to validate_assets.
Common situations: Pointing validate_assets at the bundle's receipt.json instead of the asset receipt; upgrading tasteforge so old receipts have a previous schema id; copying an arbitrary JSON file as receipt.
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
- artifact path must be a non-empty relative path
- receipt contains duplicate artifact paths
- receipt contains an invalid source
- receipt must be a list
- Unsupported canonical session schema version
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5401728e741cc8f1.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:223
receipt['bundle_receipt'] = binding
if 'genre_spec' in config:
receipt['genre_spec'] = _fingerprint(_path(config['genre_spec'], base))
# All inputs already exist, so the output-exists gate also prevents collisions.
try:
with output.open('x', encoding='utf-8') as stream:
json.dump(receipt, stream, indent=2, sort_keys=True)
stream.write('\n')
except OSError as exc:
raise ValueError(f'Cannot create exclusive receipt: {output}') from exc
return receipt
def validate_assets(receipt_path: str | Path) -> dict[str, Any]:
"""Re-hash every bound file and validate receipt semantics; no remote calls."""
path = _path(receipt_path, Path.cwd())
receipt = _load(path)
if receipt.get('schema') != SCHEMA:
raise ValueError('Unsupported asset receipt schema')
if type(receipt.get('provider_calls')) is not int or receipt['provider_calls'] != 0:
raise ValueError('Local ingestion must have zero provider calls')
if receipt.get('provider_execution') is not False:
raise ValueError('Local ingestion cannot claim provider execution')
_, requests = (_bundle(receipt['bundle_receipt'], path.parent, True)
if 'bundle_receipt' in receipt else (None, {}))
for asset in _assets(receipt.get('assets')):
_taste(asset, requests, True)
_verify_binding(asset, path.parent, asset['modality'])
provenance = _provenance(asset, path.parent, True)
if provenance is not None and provenance != asset['provider_provenance']:
raise ValueError('Invalid supplied provenance declaration')
inputs = receipt.get('input_artifacts')
if not isinstance(inputs, list):
raise ValueError('input_artifacts must be a list')
for artifact in inputs:
_verify_binding(artifact, path.parent)
if 'genre_spec' in receipt:View on GitHub (pinned to 8321021c54)