affaan-m/ECC · error · ValueError
Local ingestion must have zero provider calls
Error message
Local ingestion must have zero provider calls
What it means
validate_assets enforces that a receipt declares provider_calls as an integer equal to 0. This library only performs local hashing/binding; any claim of provider calls invalidates the receipt's local-only guarantee. Non-integer or nonzero values are rejected, including booleans (type check excludes bool via type(...) is not int).
Solutions
- Use receipts produced by ingest_assets, which always sets provider_calls: 0.
- Remove any provider-executing steps from the ingestion flow; this module forbids provider execution by design.
- If a receipt legitimately used providers, it cannot be validated with validate_assets — keep it in a separate workflow.
- Never hand-edit provider_calls; re-ingest to get a valid receipt.
Example fix
# before (hand-edited receipt)
{"schema": "tasteforge.assets.v1", "provider_calls": 2, ...}
# after: regenerate via ingest_assets; it writes provider_calls: 0
receipt = ingest_assets('config.json', 'receipt.json') Defensive patterns
Strategy: validation
Validate before calling
r = json.load(open(p))
pc = r.get('provider_calls')
assert type(pc) is int and pc == 0, 'receipt must record zero provider calls' Type guard
def zero_provider_calls(obj) -> bool:
pc = obj.get('provider_calls')
return type(pc) is int and pc == 0 Prevention
- Never merge provider-executing receipts into this local-only flow.
- Treat receipts as immutable; regenerate instead of editing.
- Note the type check rejects bool: keep the field a true JSON integer 0.
When it happens
Trigger: Calling validate_assets on a hand-edited receipt where provider_calls was changed or removed; a receipt assembled by another tool that records provider usage; provider_calls set to true/1.0/"0" or other non-int types.
Common situations: Merging receipts from a provider-executing pipeline with local ones; manual edits to make a receipt 'look complete'; custom tooling writing its own receipts that include provider calls.
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 byte size does not match receipt
- Local ingestion cannot claim provider execution
- receipt binds missing artifact
- unbound emitted artifact
- application bundle differs from its bound evidence
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/a53b09cb00df2e1b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:225
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:
_verify_binding(receipt['genre_spec'], path.parent)
return receiptView on GitHub (pinned to 8321021c54)