affaan-m/ECC · error · ValueError
Asset taste lineage differs from its bundle request
Error message
Asset taste lineage differs from its bundle request
What it means
In _taste with verify=True (validate_assets path), the asset's stored taste fields (request_id, genre_number, genre_slug, style_fingerprint, reference_sha256) are compared against the values recorded in the bundle request. Any difference — including a mutated request_id or tampered lineage in the receipt — raises this error. The receipt's lineage must be byte-identical to what the validated bundle records.
Solutions
- Re-run ingest_assets against the correct bundle to produce a fresh receipt instead of editing the old one.
- Diff the receipt asset fields against <bundle_dir>/manifests/<modality>.json requests to find the differing field.
- If the bundle changed since ingest, restore the original bundle (validated by its receipt fingerprint) or re-ingest with the new bundle.
- Do not mutate request_id on a receipt record; it must equal the bundle request's id.
Example fix
# before: hand-edited receipt asset
{"request_id": "req-001", "genre_slug": "cyberpunk-noir", ...}
# after: regenerate the receipt from the bundle
receipt = ingest_assets('ingest.config.json', 'receipt.new.json') Defensive patterns
Strategy: validation
Validate before calling
def lineage_matches(asset, request):
fields = ('request_id','genre_number','genre_slug','style_fingerprint','reference_sha256')
return all(asset.get(k) == request.get(k) for k in fields)
# check each receipt asset against its bundle manifest request before validate_assets Try / catch
try:
validate_assets('receipt.json')
except ValueError as e:
if 'taste lineage differs' in str(e):
reingest_fresh_receipt()
else:
raise Prevention
- Never hand-edit receipts; treat them as immutable artifacts.
- Keep the exact bundle used at ingest alongside the receipt (its fingerprint is in bundle_receipt).
- Re-ingest after any bundle change instead of patching receipts.
- Store receipts read-only in VCS.
When it happens
Trigger: Calling validate_assets on a receipt whose asset record's request_id or any _TASTE_FIELDS value differs from the corresponding bundle manifest request; hand-editing a receipt's genre fields; re-validating a receipt against a different (newer) bundle than the one used at ingest time.
Common situations: Manual receipt edits (fixing fields by hand); receipts copied across projects and re-validated against a different bundle; bundle regenerated so request contents changed while the old receipt was kept; accidental asset-record mutation during post-processing scripts.
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
- application bundle differs from its bound evidence
- 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/39354cc498b4ccc1.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:174
requests[key] = request
if binding != _fingerprint(root / 'receipt.json'):
raise ValueError('Bundle changed during validation')
return binding, requests
def _taste(asset: dict[str, Any], requests: dict[Any, Any], verify: bool) -> dict[str, Any]:
if not requests:
if any(key in asset for key in (*_TASTE_FIELDS, 'request_id')):
raise ValueError('Taste claims require a validated bundle')
return {}
request_id = _text(asset.get('request_id'), 'bundle request_id')
request = requests.get((asset['modality'], request_id))
if request is None:
raise ValueError('Asset request_id/modality does not match the bundle')
result = dict(request_id=request_id, **{key: request[key] for key in _TASTE_FIELDS})
if verify:
if any(asset.get(key) != value for key, value in result.items()):
raise ValueError('Asset taste lineage differs from its bundle request')
elif any(key in asset for key in _TASTE_FIELDS):
raise ValueError('Taste fields are derived from the bundle, not supplied')
return result
def ingest_assets(config_path: str | Path, out_receipt: str | Path) -> dict[str, Any]:
"""Bind local assets/provenance/lineage; write a new receipt, never overwrite."""
config_file = _path(config_path, Path.cwd())
config = _load(config_file)
base = config_file.parent
output = _path(out_receipt, Path.cwd())
if output.exists():
raise ValueError(f'Receipt output already exists: {output}')
binding, requests = (_bundle(config['bundle_dir'], base, False)
if 'bundle_dir' in config else (None, {}))
records = []
for asset in _assets(config.get('assets')):
record = {key: asset[key] for key in ('id', 'modality', 'origin')}View on GitHub (pinned to 8321021c54)