affaan-m/ECC · error · ValueError

resolve_duration must be finite and positive

Error message

resolve_duration must be finite and positive

What it means

The effect recipe builder accepts an optional explicit resolve_duration from config. If provided, it must be a finite real number greater than zero; NaN, infinity, strings, negatives, and zero are rejected to keep timeline math well-defined.

Solutions

  1. Set resolve_duration to a positive finite number (e.g. 8.5) in the config, or remove the key to auto-derive from measured source durations
  2. Validate the config value with a quick check before running
  3. Fix templating/serialization that emits strings or NaN instead of numbers

Example fix

// before
"resolve_duration": "8s"
// after
"resolve_duration": 8.0
Defensive patterns

Strategy: validation

Validate before calling

import math
d = config.get("resolve_duration")
if d is not None:
    assert isinstance(d, (int, float)) and not isinstance(d, bool) and math.isfinite(d) and d > 0, \
        "resolve_duration must be a finite positive number"

Type guard

def is_valid_duration(v) -> bool:
    import math
    return (isinstance(v, (int, float)) and not isinstance(v, bool)
            and math.isfinite(v) and v > 0)

Try / catch

try:
    run_workflow(config)
except ValueError as e:
    if "resolve_duration" in str(e):
        config["resolve_duration"] = None  # fall back to measured durations
        run_workflow(config)
    else:
        raise

Prevention

When it happens

Trigger: Config JSON contains resolve_duration set to 0, a negative number, a non-numeric value, null-like strings, NaN/Infinity, or a string like "8.5" that _finite_real rejects.

Common situations: Hand-edited YAML/JSON configs; copying a duration value with units ("8s"); templating bugs emitting empty strings; float formatting producing NaN.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

    }[modality]
    return base + suffix


def _build_effect_recipe(
    config: dict[str, Any], specs: list[dict[str, Any]], references: list[dict[str, Any]]
) -> dict[str, Any]:
    """Build a deterministic, seeded, non-periodic Resolve placement plan."""
    seed = int(config["seed"])
    rng = random.Random(seed)
    by_genre = {
        spec["number"]: [ref for ref in references if ref["genre_number"] == spec["number"]]
        for spec in specs
    }
    configured_duration = config.get("resolve_duration")
    if configured_duration is not None and (
        not _finite_real(configured_duration) or float(configured_duration) <= 0
    ):
        raise ValueError("resolve_duration must be finite and positive")
    duration = float(configured_duration or sum(
        spec["measured_features"]["total_duration"] for spec in specs
    ))
    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:

View on GitHub (pinned to 8321021c54)