affaan-m/ECC · error · ContractError
effect recipe must declare a finite positive timeline…
Error message
effect recipe must declare a finite positive timeline duration
What it means
The recipe must declare timeline_duration as a finite real number (int or float, not NaN/inf, not bool/str). This first check fires when the value is missing, of the wrong type, or non-finite; the validator needs a usable timeline to bound all events.
Solutions
- Set recipe['timeline_duration'] to a finite positive float (e.g. 30.0).
- Parse duration strings to numbers before validation (strip units, float(...)).
- Check upstream arithmetic for NaN/inf sources (math.isfinite guard).
Example fix
# before recipe["timeline_duration"] = "30s" # after recipe["timeline_duration"] = 30.0
Defensive patterns
Strategy: validation
Validate before calling
tl = recipe.get("timeline_duration")
if not (isinstance(tl, (int, float)) and not isinstance(tl, bool) and math.isfinite(tl)):
raise ValueError("timeline_duration must be a finite real number") Type guard
def has_finite_timeline(recipe: dict) -> bool:
tl = recipe.get("timeline_duration")
return (isinstance(tl, (int, float)) and not isinstance(tl, bool)
and math.isfinite(tl)) Try / catch
try:
validate_effect_recipe(recipe)
except ContractError as exc:
if "finite positive timeline duration" in str(exc):
recipe = {**recipe, "timeline_duration": float(timeline_from_config)}
validate_effect_recipe(recipe)
else:
raise Prevention
- Parse duration strings (strip units) to floats before building the recipe.
- Guard upstream duration math with math.isfinite.
- Never leave timeline placeholders unfilled in templates.
When it happens
Trigger: validate_effect_recipe called with a recipe missing 'timeline_duration', or where it is None, a string like '30s', a bool, NaN, or +/-inf.
Common situations: Parsing durations from config files where the unit suffix was kept as a string; a template that left the placeholder unfilled; JSON serialization of Infinity producing a non-standard token; dividing by zero upstream yielding inf.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- base_track_count exceeds target video tracks
- clip has no 'path
- clip has no 'path
- clip ( ) has non-positive duration
- clip ( ) has non-positive duration
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/439a9cb0dbc65d4f.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:191
def validate_effect_recipe(
recipe: dict[str, Any], *, reference_durations: dict[str, float] | None = None
) -> None:
"""Require a seeded aperiodic schedule and anchors on subject-aware effects."""
if (recipe.get("dry_run") is not True
or type(recipe.get("provider_calls")) is not int
or recipe.get("provider_calls") != 0
or recipe.get("provider_execution") is not False):
raise ContractError("effect recipe crosses the dry-run provider boundary")
if not isinstance(recipe.get("seed"), int) or isinstance(recipe.get("seed"), bool):
raise ContractError("effect recipe must have an integer seed")
if recipe.get("rng_algorithm") != "python.random.Random/v1":
raise ContractError("effect recipe must declare its seeded RNG algorithm")
events = recipe.get("events")
if not isinstance(events, list) or len(events) < 3:
raise ContractError("effect recipe needs at least three scheduled events")
timeline = recipe.get("timeline_duration")
if not _is_finite_real(timeline):
raise ContractError("effect recipe must declare a finite positive timeline duration")
timeline = cast(float, timeline)
if float(timeline) <= 0:
raise ContractError("effect recipe must declare a finite positive timeline duration")
for event in events:
start = event.get("time")
duration = event.get("duration")
if (not _is_finite_real(start) or not _is_finite_real(duration)
or float(start) < 0 or float(duration) <= 0):
raise ContractError("effect event start and duration must be finite positive timeline values")
start = cast(float, start)
duration = cast(float, duration)
if float(start) + float(duration) > float(timeline) + 1e-9:
raise ContractError("effect event end exceeds the declared timeline")
evidence = event.get("evidence")
if not isinstance(evidence, dict):
raise ContractError(f"effect {event.get('effect')} lacks reference evidence")
_validate_media_time(
evidence.get("time"), evidence.get("source_duration"), label="effect evidence time"View on GitHub (pinned to 8321021c54)