affaan-m/ECC · error · ValueError
Bundle changed during validation
Error message
Bundle changed during validation
What it means
The library fingerprints receipt.json before and after reading the manifests; if the receipt's fingerprint differs from the binding computed at bundle open, the bundle was modified concurrently during validation and results can't be trusted.
Solutions
- Re-run validation once the bundle is quiescent (no writers active)
- Lock or serialize the pipeline so nothing writes to the bundle during validation
- Exclude the bundle directory from live sync/backup tools during validation runs
Example fix
// before validate_assets(...) # while generation job still writing to bundle // after wait_for_generation_job_to_finish(); validate_assets(...)
Defensive patterns
Strategy: retry
Try / catch
for attempt in range(3):
try:
return validate_assets(assets, bundle_root=root)
except ValueError as e:
if str(e) == "Bundle changed during validation" and attempt < 2:
wait_until_bundle_quiescent(root); continue
raise Prevention
- Ensure no generation/writing jobs run against the bundle during validation
- Pause cloud-sync clients for bundle directories during CI runs
- Serialize validation and rebuild steps with a lock or job dependency
When it happens
Trigger: Another process writing to the bundle (regenerating artifacts, updating receipts) while validate_assets or ingest_assets is running; a watcher/sync tool touching receipt.json mid-validation.
Common situations: Running validation while a generation pipeline is still emitting into the same bundle directory; Dropbox/OneDrive sync replacing files during a read; two CI jobs validating and rebuilding the same bundle concurrently.
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
- Refusing to hash changed install destination
- Ambiguous duplicate bundle request
- Another Nasiko lifecycle operation won lock acquisition
- Another Nasiko lifecycle operation won stale-lock recovery
- application bundle differs from its bound evidence
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/169af603d7fece3d.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:158
from .contract import validate_bundle
if verify:
binding = _verify_binding(value, base)
root = Path(binding['path']).parent
else:
root = _path(value, base)
binding = _fingerprint(root / 'receipt.json')
validate_bundle(root)
requests = {}
for modality in sorted(MODALITIES):
manifest = _load(root / 'manifests' / f'{modality}.json')
for request in manifest['requests']:
key = (modality, _text(request.get('request_id'), 'request_id'))
if key in requests:
raise ValueError('Ambiguous duplicate bundle request')
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')View on GitHub (pinned to 8321021c54)