affaan-m/ECC · error · ValueError

cadence has no measured shot durations to plan from

Error message

cadence has no measured shot durations to plan from

What it means

`plan_shots` builds shot durations from `cadence['shots']` when available; if the cadence has no usable measured shots AND no `mean_shot` fallback value, there is nothing to plan from, so it raises. Note the inner loop already validates each shot duration via `_positive`, so only valid positive shots are kept.

Solutions

  1. Provide `mean_shot` in the cadence dict as a fallback (a positive number)
  2. Regenerate cadence.json by running the measurement step on the source edit so `shots` is populated
  3. Guard before calling: `if not cadence.get('shots') and 'mean_shot' not in cadence: raise`
  4. Fix the shot detector so at least some valid (positive, > _MIN_SHOT) durations are produced

Example fix

// before
plan_shots({}, 10.0)
// after
plan_shots({"mean_shot": 2.5}, 10.0)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(cadence, dict) or not (cadence.get("shots") or "mean_shot" in cadence):
    raise ValueError("cadence has no shots or mean_shot")

Type guard

def has_plannable_cadence(cadence) -> bool:
    return isinstance(cadence, dict) and (
        any(isinstance(s, dict) and isinstance(s.get("duration"), (int, float))
            for s in cadence.get("shots", []))
        or isinstance(cadence.get("mean_shot"), (int, float))
    )

Try / catch

try:
    planned = plan_shots(cadence, target)
except ValueError as exc:
    if "no measured shot durations" in str(exc):
        planned = plan_shots({"mean_shot": DEFAULT_MEAN_SHOT}, target)
    else:
        raise

Prevention

When it happens

Trigger: `plan_shots({}, 10.0)` or a cadence.json like `{}` / `{"shots": []}` / `{"shots": [{"duration": 0}]}` (all filtered out) with no `mean_shot` key present.

Common situations: An interrupted measurement pipeline that wrote an empty cadence.json; a pack built before any shots were detected; hand-authored cadence files that omit both `shots` and `mean_shot`; all shot durations filtered out because they were 0/invalid.

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


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/9011f5b8c3156a6f. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/apply.py:116



def plan_shots(cadence: dict[str, Any], target_duration: float) -> list[float]:
    """Propose shot durations filling ``target_duration`` at this cadence.

    Samples from the reference's own shot-length distribution (seeded, like
    the recovered ``Cadence.plan_shots``) so the plan inherits rhythm
    variance instead of flattening into evenly spaced clips.
    """
    target_duration = _positive(target_duration, "target duration")
    durations = [
        _positive(s["duration"], "cadence shot duration")
        for s in cadence.get("shots", [])
        if isinstance(s, dict) and _positive(s.get("duration"), "cadence shot duration") > _MIN_SHOT
    ]
    if not durations:
        if "mean_shot" not in cadence:
            raise ValueError("cadence has no measured shot durations to plan from")
        durations = [max(_positive(cadence.get("mean_shot"), "mean shot duration"), 1.0)]

    rng = random.Random(7)  # deterministic, mirrors numpy default_rng(7)
    out: list[float] = []
    acc = 0.0
    while acc < target_duration:
        d = rng.choice(durations)
        remaining = target_duration - acc
        if remaining < d * 0.5:
            break
        d = min(d, remaining)
        out.append(round(d, 3))
        acc += d
    if not out:
        out = [round(target_duration, 3)]
    return out

View on GitHub (pinned to 8321021c54)