affaan-m/ECC · error · ValueError
Missing artifact binding
Error message
Missing artifact binding
What it means
Every provider_provenance must include an artifact binding: a dict with a 'path' plus expected fingerprint fields (bytes, etc.). The library throws this in _verify_binding when the binding value is missing or not a dict, because there is nothing to fingerprint-verify against.
Solutions
- Add an 'evidence' dict under provider_provenance containing 'path' and the recorded fingerprint fields (bytes, hash values)
- Regenerate the binding by re-fingerprinting the artifact with the library's fingerprint helper instead of hand-writing it
- If evidence cannot be supplied, mark the provenance verification as supplied_local_evidence_only by using evidence_path instead of verify mode
Example fix
// before
"provider_provenance": {"provider": "acme", "request_id": "r1"}
// after
"provider_provenance": {"provider": "acme", "request_id": "r1",
"evidence": {"path": "artifacts/a1.png", "bytes": 1024, "sha256": "..."}} Defensive patterns
Strategy: validation
Validate before calling
for a in assets:
p = a.get("provider_provenance") or {}
ev = p.get("evidence")
if a.get("origin") == "external_result" and not (isinstance(ev, dict) and ev.get("path")):
raise ValueError(f"asset {a['id']}: missing artifact binding (evidence dict with path)") Type guard
def has_binding(p: dict | None) -> bool:
return isinstance(p, dict) and isinstance(p.get("evidence"), dict) and bool(p["evidence"].get("path")) Try / catch
try:
ingest_assets(assets)
except ValueError as e:
if str(e) == "Missing artifact binding":
regenerate_bindings(assets); retry()
else:
raise Prevention
- Generate bindings with the library's fingerprint helper instead of hand-writing them
- Keep evidence blocks adjacent to provenance in your manifest templates
- Schema-validate that external_result assets always include an evidence object
When it happens
Trigger: provider_provenance lacking the 'evidence' key while verify=true; evidence set to null/string; validate_assets checking an asset whose binding was dropped during manifest editing.
Common situations: Hand-written manifests forgetting the evidence block; tooling serializing evidence as a stringified path; deleting evidence entries to 'clean up' manifests.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- a generated candidate cannot claim original-source identity
- anchor evidence source duration is not bound to its receipt…
- artifact cites an unknown provenance source
- artifact has an unbound source duration
- artifact has invalid reference path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/9d09e1002beea58b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:129
return None
if not isinstance(source, dict):
raise ValueError('external_result requires provider provenance and local evidence')
provider = _text(source.get('provider'), 'provider')
identifiers = {key: _text(source[key], key) for key in ('request_id', 'workflow_id')
if key in source}
if not identifiers:
raise ValueError('Provider provenance requires request_id or workflow_id')
if verify:
evidence = _verify_binding(source.get('evidence'), base)
else:
evidence = _fingerprint(_path(source.get('evidence_path'), base))
return dict(provider=provider, **identifiers, evidence=evidence,
verification='supplied_local_evidence_only')
def _verify_binding(value: Any, base: Path, modality: str | None = None) -> dict[str, Any]:
if not isinstance(value, dict):
raise ValueError('Missing artifact binding')
actual = _fingerprint(_path(value.get('path'), base), modality)
if type(value.get('bytes')) is not int or any(value.get(k) != v for k, v in actual.items()):
raise ValueError(f'Artifact changed or binding invalid: {actual["path"]}')
return actual
_TASTE_FIELDS = ('genre_number', 'genre_slug', 'style_fingerprint', 'reference_sha256')
def _bundle(value: Any, base: Path, verify: bool) -> tuple[dict[str, Any], dict[tuple[str, str], Any]]:
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')View on GitHub (pinned to 8321021c54)