{"record":{"id":"0d6f7066b5165066","repo":"affaan-m/ECC","slug":"input-artifacts-must-be-a-list","errorCode":null,"errorMessage":"input_artifacts must be a list","messagePattern":"input_artifacts must be a list","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/assets.py","lineNumber":238,"sourceCode":"    path = _path(receipt_path, Path.cwd())\n    receipt = _load(path)\n    if receipt.get('schema') != SCHEMA:\n        raise ValueError('Unsupported asset receipt schema')\n    if type(receipt.get('provider_calls')) is not int or receipt['provider_calls'] != 0:\n        raise ValueError('Local ingestion must have zero provider calls')\n    if receipt.get('provider_execution') is not False:\n        raise ValueError('Local ingestion cannot claim provider execution')\n    _, requests = (_bundle(receipt['bundle_receipt'], path.parent, True)\n                   if 'bundle_receipt' in receipt else (None, {}))\n    for asset in _assets(receipt.get('assets')):\n        _taste(asset, requests, True)\n        _verify_binding(asset, path.parent, asset['modality'])\n        provenance = _provenance(asset, path.parent, True)\n        if provenance is not None and provenance != asset['provider_provenance']:\n            raise ValueError('Invalid supplied provenance declaration')\n    inputs = receipt.get('input_artifacts')\n    if not isinstance(inputs, list):\n        raise ValueError('input_artifacts must be a list')\n    for artifact in inputs:\n        _verify_binding(artifact, path.parent)\n    if 'genre_spec' in receipt:\n        _verify_binding(receipt['genre_spec'], path.parent)\n    return receipt\n","sourceCodeStart":220,"sourceCodeEnd":244,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/assets.py#L220-L244","documentation":"validate_assets checks that a receipt's input_artifacts field is a JSON list before iterating and verifying binding hashes for each entry. The library throws this when the receipt declares input_artifacts as anything other than an array (string, dict, null, number). It guards the for-loop from TypeError and enforces the receipt schema contract.","triggerScenarios":"Calling validate_assets on a receipt JSON where 'input_artifacts' is absent (None), a single object instead of a list, a comma-joined string of paths, or otherwise not a JSON array.","commonSituations":"Hand-edited receipt JSON, scripts that emit a single artifact object when only one input exists, receipts serialized from non-list languages/collections, or receipts generated by older tool versions with a different schema.","solutions":["Edit the receipt so input_artifacts is a JSON array of artifact objects (wrap a single object in []).","If input_artifacts is intentionally empty, set it to [] rather than omitting it or null.","Regenerate the receipt with the matching tasteforge version that produces the expected schema.","Remove stray hand edits / re-export the receipt from source JSON rather than manual patching."],"exampleFix":"// before\n\"input_artifacts\": {\"path\": \"a.png\", \"sha256\": \"...\"}\n// after\n\"input_artifacts\": [{\"path\": \"a.png\", \"sha256\": \"...\"}]","handlingStrategy":"validation","validationCode":"def is_valid_receipt(receipt):\n    return isinstance(receipt, dict) and isinstance(receipt.get('input_artifacts'), list)","typeGuard":"def has_input_artifacts_list(receipt) -> bool:\n    return isinstance(receipt, dict) and isinstance(receipt.get('input_artifacts'), list)","tryCatchPattern":"try:\n    validate_assets(receipt_path)\nexcept ValueError as e:\n    if 'input_artifacts must be a list' in str(e):\n        receipt['input_artifacts'] = list(receipt.get('input_artifacts') or [])\n    else:\n        raise","preventionTips":["Always serialize input_artifacts as a JSON array, even for a single artifact","Use [] instead of null/omission for empty inputs","Validate receipt JSON against the schema before feeding it to validate_assets","Avoid hand-editing generated receipts; regenerate them with the tool"],"tags":["python","validation","schema"],"backgroundTag":"type-mismatch","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}