affaan-m/ECC · error · ValueError
target duration must contain at least one frame
Error message
target duration must contain at least one frame
What it means
`_strict_assign` converts the requested target duration into an integer frame count using `timeline.seconds_to_frames(target, fps)`. If the result is < 1, the target duration cannot hold even a single frame at the given frame rate, so there is nothing to assign and it raises. Called by `apply_local`.
Solutions
- Increase target_duration so it covers at least one frame (>= 1/fps seconds)
- Verify the unit is seconds, not milliseconds or frames
- Raise fps so a frame is short enough for the requested duration
- Pre-check: `seconds_to_frames(target, fps) >= 1` before calling
Example fix
// before apply_local(..., target=0.02, fps=30) # < 1 frame // after apply_local(..., target=max(0.02, 1/30), fps=30)
Defensive patterns
Strategy: validation
Validate before calling
if timeline.seconds_to_frames(target, fps) < 1:
raise ValueError("target duration shorter than one frame") Try / catch
try:
report = apply_local(media=media, sp=sp, target=target, fps=fps)
except ValueError as exc:
if "at least one frame" in str(exc):
target = 1.0 / fps
report = apply_local(media=media, sp=sp, target=target, fps=fps)
else:
raise Prevention
- Pre-check frame count >= 1 for any user-supplied duration
- Ensure durations are in seconds, not milliseconds or frames
- Document the minimum representable duration (1/fps) in your CLI/config
When it happens
Trigger: Calling `apply_local` with a target duration shorter than one frame period (e.g. 0.02s at 30fps, where one frame ≈ 0.0333s), or a duration that rounds down to 0 frames.
Common situations: User asks for a 1-frame-looking clip but passes duration in milliseconds instead of seconds; very low fps values making frame periods long; target computed from another unit conversion error.
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
- cadence shot cannot occupy a whole frame
- clip ( ) has non-positive duration
- clip ( ) has non-positive duration
- asset contains too few frames
- base_track_count exceeds target video tracks
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/7896c8abf77aaa36.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/apply.py:61
def _positive(value: Any, label: str) -> float:
if isinstance(value, bool):
raise ValueError(f"{label} must be finite and positive")
try:
number = float(value)
except (TypeError, ValueError, OverflowError) as exc:
raise ValueError(f"{label} must be finite and positive") from exc
if not math.isfinite(number) or number <= 0:
raise ValueError(f"{label} must be finite and positive")
return number
def _strict_assign(
planned: list[float], media: list[dict[str, Any]], target: float, fps: float
) -> list[tuple[dict[str, Any], int]]:
"""Fill the target frame count, then match whole shots to unique sources."""
target_frames = timeline.seconds_to_frames(target, fps)
if target_frames < 1:
raise ValueError("target duration must contain at least one frame")
frame_counts = []
elapsed = 0.0
assigned = 0
for duration in planned:
if assigned == target_frames:
break
elapsed += duration
boundary = min(target_frames, timeline.seconds_to_frames(elapsed, fps))
if boundary <= assigned:
raise ValueError("cadence shot cannot occupy a whole frame")
frame_counts.append(boundary - assigned)
assigned = boundary
if assigned < target_frames:
frame_counts.append(target_frames - assigned)
rate = timeline.fps_fraction(fps)
sources: dict[str, tuple[dict[str, Any], int]] = {}
for clip in media:View on GitHub (pinned to 8321021c54)