{"record":{"id":"b34a2fd824aa1cd0","repo":"calesthio/OpenMontage","slug":"scene-pacing-check-failed-errors-joined-by-n","errorCode":null,"errorMessage":"Scene pacing check failed:\n  - {errors joined by newline}","messagePattern":"Scene pacing check failed:\n  - (.+?)","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"lib/verify_scene_pacing.py","lineNumber":129,"sourceCode":"            )\n\n    # Overflow check\n    cursor = sum(step_duration(s, fps) for s in steps)\n    end_vt = scene_start + cursor\n    scene_duration = scene_end - scene_start\n    if cursor > scene_duration + 0.5:\n        errors.append(\n            f\"steps overflow scene: cursor ends at {end_vt:.2f}s but scene_end is {scene_end:.2f}s \"\n            f\"(overflow {cursor - scene_duration:.2f}s)\"\n        )\n    if cursor < scene_duration - 5.0:\n        errors.append(\n            f\"steps underfill scene by {scene_duration - cursor:.2f}s — last visible step holds \"\n            f\"frozen from {end_vt:.2f}s to {scene_end:.2f}s. Add a closer pause.\"\n        )\n\n    if errors:\n        raise AssertionError(\n            \"Scene pacing check failed:\\n  - \" + \"\\n  - \".join(errors)\n        )\n\n\n__all__ = [\"step_duration\", \"trace\", \"assert_alignment\", \"Landmark\"]\n","sourceCodeStart":111,"sourceCodeEnd":135,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/lib/verify_scene_pacing.py#L111-L135","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"# before\n# steps end at 12.4s but scene is 20s -> underfill error\nassert_alignment(steps, 0.0, 20.0, cues)\n\n# after\nsteps.append({\"kind\": \"pause\", \"seconds\": 7.6})  # close the scene\nassert_alignment(steps, 0.0, 20.0, cues)","handlingStrategy":"validation","validationCode":"from lib.verify_scene_pacing import trace, step_duration\n\ndef pacing_will_pass(steps, scene_start, scene_end, fps=30):\n    cursor = sum(step_duration(s, fps) for s in steps)\n    dur = scene_end - scene_start\n    return (dur - 5.0) <= cursor <= (dur + 0.5)\n\nlandmarks = trace(steps, scene_start, fps, quiet=True)\n# ensure every cue is within tolerance of some landmark before asserting","typeGuard":"def cues_aligned(landmarks, cues, tolerance=1.0) -> bool:\n    return all(\n        any(abs(lm.video_time - t) <= tolerance for lm in landmarks)\n        for t, _ in cues\n    )","tryCatchPattern":"try:\n    assert_alignment(steps, scene_start, scene_end, cues)\nexcept AssertionError as e:\n    # message lists every violation at once — fix the batch, then re-run\n    log.warning(\"pacing failed:\\n%s\", e)\n    raise","preventionTips":["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."],"tags":["scene","pacing","assertion","video","sync"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}