affaan-m/ECC · error · ValueError
assets must be a nonempty list
Error message
assets must be a nonempty list
What it means
_assets validates the manifest's assets field and requires it to be a list with at least one element. If assets is missing, null, not a list (e.g., a dict or string), or an empty list, this error is raised from ingest_assets or validate_assets.
Solutions
- Add at least one asset entry under the 'assets' key of the manifest.
- Check for key typos — the field must be exactly 'assets'.
- If no assets are expected, skip calling ingest_assets/validate_assets rather than passing an empty manifest.
- Fix the upstream filter/generation step that produced an empty asset list.
Example fix
// before
{"assets": []}
// after
{"assets": [{"id": "hero", "modality": "image", "origin": "local", "path": "hero.png"}]} Defensive patterns
Strategy: validation
Validate before calling
import json
data = json.load(open(path))
assets = data.get('assets')
assert isinstance(assets, list) and len(assets) > 0, 'assets must be a nonempty list' Type guard
def has_assets(v) -> bool:
return isinstance(v, dict) and isinstance(v.get('assets'), list) and len(v['assets']) > 0 Try / catch
try:
ingest_assets(path)
except ValueError as e:
if str(e) == 'assets must be a nonempty list':
skip_ingest_or_fix_manifest(path) Prevention
- Verify manifest templates ship with a sample asset
- Check for 'assets' key typos in generators
- Skip library calls entirely when no assets exist
When it happens
Trigger: Manifest JSON has no 'assets' key, assets: null, assets: {}, assets: "...", or assets: [].
Common situations: Newly created template manifest with an empty assets array; key typo ("asset" instead of "assets"); a filter step that removed all assets leaving an empty list.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Each asset must be an object
- invalid or empty manifest
- -32602
- artifact path must be a non-empty relative path
- built an invalid spec
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/964cab10e7cc23e7.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/assets.py:90
if magic != b'glTF' or version != 2 or size != final.st_size:
raise ValueError(f'Invalid GLB magic, version or declared size: {path}')
return dict(path=str(path), bytes=final.st_size, sha256=digest.hexdigest())
def _load(path: Path) -> dict[str, Any]:
_fingerprint(path)
try:
data = json.loads(path.read_text(encoding='utf-8'))
except (ValueError, OSError) as exc:
raise ValueError(f'Cannot read JSON object: {path}') from exc
if not isinstance(data, dict):
raise ValueError('Expected a JSON object')
return data
def _assets(value: Any) -> list[dict[str, Any]]:
if not isinstance(value, list) or not value:
raise ValueError('assets must be a nonempty list')
ids = set()
for asset in value:
if not isinstance(asset, dict):
raise ValueError('Each asset must be an object')
asset_id = _text(asset.get('id'), 'asset id')
if asset_id in ids:
raise ValueError(f'Duplicate asset id: {asset_id}')
ids.add(asset_id)
if asset.get('modality') not in tuple(MODALITIES):
raise ValueError('modality must be image, video or 3d_asset')
if asset.get('origin') not in tuple(ORIGINS):
raise ValueError('Invalid asset origin')
return value
def _provenance(asset: dict[str, Any], base: Path, verify: bool) -> dict[str, Any] | None:
source = asset.get('provider_provenance')
if asset['origin'] != 'external_result':View on GitHub (pinned to 8321021c54)