calesthio/OpenMontage · error · AssertionError
Scene pacing check failed: - {errors joined by newline}
Error message
Scene pacing check failed:
- {errors joined by newline} What it means
Raised by lib/verify_scene_pacing.py's assert_alignment() as an AssertionError when one or more pacing checks fail: a narration cue has no visual landmark within the tolerance (default ±1.0s), the total step duration overflows the scene window by more than 0.5s, or the steps underfill the scene by more than 5.0s (last visible step would hold frozen). All violations are collected and reported together in one message, so fix them as a batch.
Source
Thrown at lib/verify_scene_pacing.py:129
)
# Overflow check
cursor = sum(step_duration(s, fps) for s in steps)
end_vt = scene_start + cursor
scene_duration = scene_end - scene_start
if cursor > scene_duration + 0.5:
errors.append(
f"steps overflow scene: cursor ends at {end_vt:.2f}s but scene_end is {scene_end:.2f}s "
f"(overflow {cursor - scene_duration:.2f}s)"
)
if cursor < scene_duration - 5.0:
errors.append(
f"steps underfill scene by {scene_duration - cursor:.2f}s — last visible step holds "
f"frozen from {end_vt:.2f}s to {scene_end:.2f}s. Add a closer pause."
)
if errors:
raise AssertionError(
"Scene pacing check failed:\n - " + "\n - ".join(errors)
)
__all__ = ["step_duration", "trace", "assert_alignment", "Landmark"]
View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Read each bullet in the message: 'overflow' means shorten steps (trim text, reduce holdSeconds/seconds) or extend scene_end; 'underfill' means add a closing pause; cue errors mean nudge cue times or step order.
- Run trace(steps, scene_start, fps) to print the landmark timeline and see exactly where the cursor lands.
- Only if genuinely needed, adjust tolerance or fps parameters — but prefer fixing the scene content, since the check exists to guarantee narration/visual sync.
Example fix
# before
# steps end at 12.4s but scene is 20s -> underfill error
assert_alignment(steps, 0.0, 20.0, cues)
# after
steps.append({"kind": "pause", "seconds": 7.6}) # close the scene
assert_alignment(steps, 0.0, 20.0, cues) Defensive patterns
Strategy: validation
Validate before calling
from lib.verify_scene_pacing import trace, step_duration
def pacing_will_pass(steps, scene_start, scene_end, fps=30):
cursor = sum(step_duration(s, fps) for s in steps)
dur = scene_end - scene_start
return (dur - 5.0) <= cursor <= (dur + 0.5)
landmarks = trace(steps, scene_start, fps, quiet=True)
# ensure every cue is within tolerance of some landmark before asserting Type guard
def cues_aligned(landmarks, cues, tolerance=1.0) -> bool:
return all(
any(abs(lm.video_time - t) <= tolerance for lm in landmarks)
for t, _ in cues
) Try / catch
try:
assert_alignment(steps, scene_start, scene_end, cues)
except AssertionError as e:
# message lists every violation at once — fix the batch, then re-run
log.warning("pacing failed:\n%s", e)
raise Prevention
- Re-run assert_alignment after any edit to scene text, holdSeconds, or scene durations.
- Use trace() to inspect the landmark timeline while authoring, not just at verification time.
- End scenes with a closing pause sized to the remaining time to avoid underfill.
When it happens
Trigger: Calling assert_alignment(steps, scene_start, scene_end, narration_cues) with steps whose computed timeline (via step_duration) doesn't fit scene_end - scene_start, or narration cue timestamps that don't line up with traced Landmark video times. Typical concrete causes: a cmd step's text too long for the scene, missing closing pause, cue times computed against a different scene_start.
Common situations: Editing scene text (longer command output changes typing duration) without re-checking pacing; scene duration changed in the edit decision list but steps not re-timed; narration generated against an older timeline; wrong fps assumption (default 30).
Related errors
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/b34a2fd824aa1cd0.
Report an issue: GitHub.