affaan-m/ECC · error · ValueError

timeline is too short for a fail-closed aperiodic effect…

Error message

timeline is too short for a fail-closed aperiodic effect schedule

What it means

Effect scheduling needs at least four valid event times within the timeline to build an aperiodic schedule. After clamping fallback positions to [0, duration - 0.08], fewer than four remain when the timeline is extremely short, so the builder fails closed instead of producing overlapping/degenerate effects.

Solutions

  1. Provide longer reference media so measured total_duration yields a usable timeline
  2. Set resolve_duration explicitly to a sane value >= 6.0 in the config
  3. Check probe output (sample_times/scene changes) — replace sources that produced no usable features

Example fix

// before
"resolve_duration": 0.5
// after
"resolve_duration": 8.0
Defensive patterns

Strategy: validation

Validate before calling

probe = probe_media(source)
dur = config.get("resolve_duration") or probe.get("total_duration", 0)
assert dur >= 6.0, f"timeline too short: {dur}s — use longer source media or set resolve_duration >= 6"

Type guard

def timeline_is_schedulable(duration: float, min_len: int = 4) -> bool:
    slots = sorted({round(duration * f, 6) for f in (0.10, 0.28, 0.53, 0.82)
                    if 0 <= duration * f <= duration - 0.08})
    return duration > 0 and len(slots) >= min_len

Try / catch

try:
    recipe = build_recipe(specs, config)
except ValueError as e:
    if "timeline is too short" in str(e):
        config["resolve_duration"] = max(6.0, config.get("resolve_duration") or 6.0)
        recipe = build_recipe(specs, config)
    else:
        raise

Prevention

When it happens

Trigger: _build_effect_recipe is called with a computed/configured duration so small (after the 6.0s floor bypass or with filtered event times) that fewer than 4 event times survive the 0..duration-0.08 filter.

Common situations: Very short reference clips with measured total_duration near zero; config resolving to a tiny duration; sources whose features yielded almost no valid timestamps.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/workflow.py:462

    duration = max(duration, 6.0)
    effect_names = {
        "flash-ethereal": "bloom_flash",
        "3d-cyber-glitch": "cv_wireframe_lock",
        "fluid-sketch": "fluid_contour_bleed",
    }
    event_times: list[float] = []
    clock = round(rng.uniform(0.35, 0.75), 6)
    while clock <= duration - 0.08 and len(event_times) < 18:
        event_times.append(clock)
        clock = round(clock + rng.uniform(0.61, 2.17), 6)

    # Short timelines use deterministic, aperiodic fallback positions rather
    # than forcing later random draws beyond the declared duration.
    if len(event_times) < 4:
        event_times.extend(round(duration * fraction, 6) for fraction in (0.10, 0.28, 0.53, 0.82))
        event_times = sorted({time for time in event_times if 0 <= time <= duration - 0.08})[:18]
    if len(event_times) < 4:
        raise ValueError("timeline is too short for a fail-closed aperiodic effect schedule")

    events: list[dict[str, Any]] = []
    for index, clock in enumerate(event_times):
        spec = specs[index % len(specs)]
        ref = by_genre[spec["number"]][index % len(by_genre[spec["number"]])]
        sample_times = ref["probe"].get("sample_times", [])
        evidence_time = float(sample_times[index % len(sample_times)]) if sample_times else 0.0
        source_duration = ref["source_duration"]
        requires_anchor = spec["slug"] == "3d-cyber-glitch"
        event_duration = round(min(rng.uniform(0.08, 0.42), duration - clock), 6)
        event: dict[str, Any] = {
            "event_id": f"fx-{index:03d}",
            "time": clock,
            "duration": event_duration,
            "genre_number": spec["number"],
            "effect": effect_names.get(spec["slug"], "reference_accent"),
            "requires_subject_anchor": requires_anchor,
            "placement": {

View on GitHub (pinned to 8321021c54)