affaan-m/ECC · error · ValueError
asset must be a local regular file
Error message
asset must be a local regular file
What it means
allocate_placements requires each event's 'asset' to be a str or pathlib.Path whose string form is nonempty; otherwise it raises ValueError('asset must be a local regular file'). This generic message fires on missing/empty/wrong-typed asset values, before the path is even resolved.
Solutions
- Ensure every event has 'asset' set to a nonempty string or pathlib.Path pointing to a local file
- Fix key typos so the path lands under 'asset'
- Download remote assets to disk first; this API works only with local files
- Pre-validate event dicts with a schema (e.g. pydantic/zod-like check: asset: str, min_length 1) before calling
Example fix
// before
{"id": "bug", "asset": ""}
// after
{"id": "bug", "asset": "/assets/ladybug.webm"} Defensive patterns
Strategy: validation
Validate before calling
def validate_assets(events):
for ev in events:
a = ev.get('asset')
if not isinstance(a, (str, __import__('pathlib').Path)) or not str(a):
raise ValueError(f'placement {ev.get("id")!r} has no asset path')
validate_assets(placements) Type guard
from pathlib import Path
def has_asset(ev) -> bool:
a = ev.get('asset')
return isinstance(a, (str, Path)) and bool(str(a)) Try / catch
try:
resolve.plan(placements, fps=fps)
except ValueError as e:
if 'asset must be a local regular file' in str(e):
raise PlacementError('a placement is missing its asset field') from e
raise Prevention
- Validate placement dicts against a schema before calling
- Fill placeholders in templated configs before rendering
- Download remote assets to local files first
When it happens
Trigger: An event dict missing 'asset', asset=None, asset='' , or asset being something else entirely (an int id, a URL string is actually accepted as a str here but will fail the next is_file() check — the type failure raises this one).
Common situations: Templated configs where a placeholder wasn't filled in; renamed key ('file' instead of 'asset'); passing a remote URL expecting the library to download it (it requires local files); passing a directory instead of a file path (type ok, but see the path-specific variant).
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
- placement id must be unique and nonempty
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
- a generated candidate cannot claim original-source identity
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/32283e2e1fb9355e.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/resolve.py:115
for event in placements:
identifier = event.get("id")
if not isinstance(identifier, str) or not identifier or identifier in seen:
raise ValueError("placement id must be unique and nonempty")
seen.add(identifier)
start = _integer(event.get("record_frame"), "record_frame")
frames = _integer(event.get("frames"), "frames", 1)
opacity = event.get("opacity")
if (
isinstance(opacity, bool)
or not isinstance(opacity, (int, float))
or not math.isfinite(opacity)
or not 0 <= opacity <= 100
):
raise ValueError("explicit opacity must be finite within 0..100")
composite = _integer(event.get("composite"), "composite")
raw_asset = event.get("asset")
if not isinstance(raw_asset, (str, Path)) or not str(raw_asset):
raise ValueError("asset must be a local regular file")
asset = Path(raw_asset).expanduser().resolve()
if not asset.is_file():
raise ValueError(f"asset must be a local regular file: {asset}")
alpha = event.get("requires_alpha", False)
if not isinstance(alpha, bool):
raise ValueError("requires_alpha must be boolean")
key = str(asset)
if key not in metadata:
metadata[key] = probe(asset)
info = metadata[key]
if _fps(info.get("fps")) != rate:
raise ValueError(f"asset fps differs from timeline: {asset}")
if _integer(info.get("frames"), "asset frames", 1) < frames:
raise ValueError(f"asset contains too few frames: {asset}")
if alpha and info.get("has_alpha") is not True:
raise ValueError(f"asset requires verified alpha: {asset}")
checked.append(
{View on GitHub (pinned to 8321021c54)