affaan-m/ECC · error · ValueError
pack has no measured cadence (cadence.json is missing)
Error message
pack has no measured cadence (cadence.json is missing)
What it means
apply_local refuses to run when the style pack's cadence.json file does not exist at sp.cadence_path. The library plans shot durations from measured cadence data, so without this file there is nothing deterministic to plan from. It fails fast with a ValueError rather than guessing or fabricating timing data.
Solutions
- Run the pack's cadence measurement/build step first so cadence.json is generated at sp.cadence_path.
- Verify sp.cadence_path points at the right location (print it and check the file exists).
- Re-ingest or rebuild the style pack if the file was lost or the directory was moved.
- Use a different, complete style pack that already contains cadence.json.
Example fix
// before
report = apply_local(sp, media=clips) # ValueError: pack has no measured cadence
// after
if not sp.cadence_path.exists():
sp = build_style_pack(...) # generates cadence.json from measured shots
report = apply_local(sp, media=clips) Defensive patterns
Strategy: validation
Validate before calling
if not sp.cadence_path.exists():
raise FileNotFoundError(f"build cadence.json first at {sp.cadence_path}") Type guard
def has_cadence(sp) -> bool:
return sp.cadence_path.is_file() Try / catch
try:
report = apply_local(sp, media=clips)
except ValueError as e:
if "cadence.json is missing" in str(e):
sp = build_style_pack(...) # regenerate
report = apply_local(sp, media=clips)
else:
raise Prevention
- Always run the cadence measurement step before apply_local.
- Check sp.cadence_path.exists() in your pipeline's preflight.
- Don't gitignore generated cadence.json if packs are shared via VCS.
When it happens
Trigger: Calling apply_local(sp, media=[...]) when the StylePack's cadence_path does not point to an existing cadence.json — e.g. the pack was never through the measure/forge step, or the pack directory was partially copied.
Common situations: Using a freshly scaffolded style pack before running the cadence measurement step; renaming or moving the pack directory so cadence_path no longer resolves; checking out a repo with the pack's media but not its generated JSON artifacts (gitignored).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Install manifests not found under
- missing modality manifests
- no style pack at - expected a pack.json manifest
- no style pack ' ' under - run mint.py first
- receipt source is unavailable
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/1739f9aebdec58c6.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/apply.py:158
no_repeat: bool = False,
) -> dict[str, Any]:
"""Plan a cut from the pack's cadence over local media clips.
With ``no_repeat=True``, normalized source paths are used at most once;
insufficient sources or source durations fail instead of repeating clips.
Strict plans fill the nearest whole-frame target and never exceed source
capacity. Media duration metadata must describe the available source.
Returns an application report validated against
``schema.APPLICATION_REPORT_SCHEMA``. The report structurally cannot
claim a provider run: ``provider`` is enum-locked to ``"none"`` and
``dry_run`` to ``true``.
"""
if not media:
raise ValueError("apply_local needs at least one media clip")
if not sp.cadence_path.exists():
raise ValueError("pack has no measured cadence (cadence.json is missing)")
cadence = sp.read_json(sp.cadence_path)
if not isinstance(cadence, dict) or not (cadence.get("shots") or "mean_shot" in cadence):
raise ValueError("cadence.json has no measured shots to plan from")
seq_fps = _positive(fps if fps is not None else cadence.get("fps", _DEFAULT_FPS), "fps")
validated_media = []
for clip in media:
if not isinstance(clip, dict) or not isinstance(clip.get("path"), (str, Path)):
raise ValueError("media clips require a local source path")
if not str(clip["path"]).strip():
raise ValueError("media clips require a local source path")
validated_media.append({**clip, "duration": _positive(clip.get("duration"), "media duration")})
target = _positive(duration if duration is not None else sum(
c["duration"] for c in validated_media
), "target duration")
planned = plan_shots(cadence, target)
assignments = _strict_assign(planned, validated_media, target, seq_fps) if no_repeat else [
(validated_media[i % len(validated_media)], max(1, timeline.seconds_to_frames(d, seq_fps)))
for i, d in enumerate(planned)View on GitHub (pinned to 8321021c54)