affaan-m/ECC · error · ContractError
effect event end exceeds the declared timeline
Error message
effect event end exceeds the declared timeline
What it means
An event must fit inside the declared timeline: start + duration may not exceed timeline_duration (with a tiny 1e-9 tolerance for float rounding). An event that ends after the timeline is inconsistent with the recipe's declared bounds and is rejected.
Solutions
- Reduce the event's duration (or start) so time + duration <= timeline_duration.
- Increase recipe['timeline_duration'] to cover all events.
- Regenerate the schedule ensuring events are laid out within the timeline bound.
Example fix
# before
{"time": 28.0, "duration": 5.0} # timeline 30.0
# after
{"time": 25.0, "duration": 5.0} # ends at 30.0 Defensive patterns
Strategy: validation
Validate before calling
for ev in recipe["events"]:
if float(ev["time"]) + float(ev["duration"]) > float(recipe["timeline_duration"]) + 1e-9:
raise ValueError(f"event {ev} ends past timeline {recipe['timeline_duration']}") Type guard
def event_fits_timeline(ev: dict, timeline: float) -> bool:
return float(ev["time"]) + float(ev["duration"]) <= float(timeline) + 1e-9 Try / catch
try:
validate_effect_recipe(recipe)
except ContractError as exc:
if "exceeds the declared timeline" in str(exc):
recipe = {**recipe, "events": [clip_event_to_timeline(ev, recipe["timeline_duration"]) for ev in recipe["events"]]}
validate_effect_recipe(recipe)
else:
raise Prevention
- Recompute timeline_duration after editing any event's start/duration.
- Generate events by laying out intervals inside the timeline, not the reverse.
- Keep event times and timeline_duration in the same unit.
When it happens
Trigger: validate_effect_recipe called where any event satisfies time + duration > timeline_duration + 1e-9, e.g. start 28.0 with duration 5.0 on a 30.0 timeline.
Common situations: Editing event durations after fixing the timeline; generating events evenly spaced across a slightly-too-short timeline; unit mismatch between event times and timeline_duration; off-by-one when events are meant to end 'at' the boundary.
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
- 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/4ad6dc43979b9399.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:204
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"
)
if reference_durations is not None:
digest = evidence.get("reference_sha256")
expected_duration = reference_durations.get(digest) if isinstance(digest, str) else None
if expected_duration is None or evidence.get("source_duration") != expected_duration:
raise ContractError("effect evidence source duration is not bound to its receipt reference")
times = [float(event["time"]) for event in events]
if times != sorted(times) or len(times) != len(set(times)):
raise ContractError("effect event times must be unique and increasing")
intervals = [round(b - a, 6) for a, b in zip(times, times[1:])] # noqa: RUF007
if len(set(intervals)) <= 1:
raise ContractError("stochastic schedule is periodic; intervals must vary")
for period in range(1, len(intervals) // 2 + 1):View on GitHub (pinned to 8321021c54)