calesthio/OpenMontage · error · ValueError
Unknown step kind
Error message
Unknown step kind: {k!r} What it means
Raised by lib/verify_scene_pacing.py's step_duration() when a scene step dict has a 'kind' value other than the four supported kinds: 'cmd', 'out', 'pause', 'pill'. Each kind has its own duration model — 'cmd' types text at typeSpeed (default 0.035s/char) plus holdSeconds (default 0.3), 'out' is a reveal of ~0.08s plus holdSeconds (default 0.15), 'pause' is its explicit seconds, 'pill' is instant (0.0). An unknown kind means the pacing verifier cannot compute the timeline and refuses to guess.
Solutions
- Correct the step to one of the four kinds: cmd, out, pause, pill (use 'pause' with seconds for waits).
- Validate kinds before tracing: assert all(s['kind'] in {'cmd','out','pause','pill'} for s in steps).
- If you added a new kind to the renderer, add a matching duration branch to step_duration() in lib/verify_scene_pacing.py.
Example fix
# before
steps = [{"kind": "wait", "seconds": 2.0}]
# after
steps = [{"kind": "pause", "seconds": 2.0}] Defensive patterns
Strategy: type-guard
Validate before calling
VALID_KINDS = {"cmd", "out", "pause", "pill"}
bad = [i for i, s in enumerate(steps) if s.get("kind") not in VALID_KINDS]
if bad:
raise ValueError(f"Invalid step kind at indices {bad}; valid kinds: {sorted(VALID_KINDS)}") Type guard
from typing import Literal
StepKind = Literal["cmd", "out", "pause", "pill"]
def steps_are_valid(steps: list[dict]) -> bool:
return all(s.get("kind") in {"cmd", "out", "pause", "pill"} for s in steps) Try / catch
try:
trace(steps, scene_start, fps)
except ValueError as e:
if "Unknown step kind" in str(e):
# bad generated steps — regenerate or repair before verifying pacing
raise SceneStepError(str(e)) from e
raise Prevention
- Validate the kind vocabulary immediately after generating or loading scene steps.
- Use 'pause' with an explicit seconds field for any wait step.
- When adding a renderer step kind, update step_duration() in the same change.
When it happens
Trigger: Feeding assert_alignment()/trace() a steps list containing a step like {'kind': 'wait', 'seconds': 2} or a typo like {'kind': 'cmdd'}; generating steps with a template or LLM that invents kind values; using a new step kind added to the renderer but not to this verifier.
Common situations: Hand-written or machine-generated scene step YAML with kind typos; renderer and verifier drifting out of sync when a new step kind is introduced; copy-pasting steps from a different scene format.
Related errors
- Scene pacing check failed
- Unknown pipeline_type
- all local reference audio clips together must be at most
- all reference audio clips together must be at most
- all reference videos together must be at most
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/44e52bae7e8dee3f.
Report an issue: GitHub.
Appendix: source
Thrown at lib/verify_scene_pacing.py:49
def step_duration(step: dict[str, Any], fps: int = 30) -> float:
"""Return the cursor-advancement for a single step (frame-accurate).
Pills DO NOT advance the cursor — they're non-blocking overlays.
"""
k = step["kind"]
if k == "cmd":
type_frames = math.ceil(len(step["text"]) * step.get("typeSpeed", 0.035) * fps)
return type_frames / fps + step.get("holdSeconds", 0.3)
if k == "out":
reveal_frames = max(2, math.ceil(0.08 * fps))
return reveal_frames / fps + step.get("holdSeconds", 0.15)
if k == "pause":
return float(step["seconds"])
if k == "pill":
return 0.0
raise ValueError(f"Unknown step kind: {k!r}")
@dataclass
class Landmark:
video_time: float
kind: str
text: str
def trace(steps: list[dict[str, Any]], scene_start: float = 0.0, fps: int = 30, *, quiet: bool = False) -> list[Landmark]:
"""Walk the step list and print a video-time landmark for each visible event.
Returns the list of landmarks (useful for alignment checks).
"""
cursor = 0.0
out: list[Landmark] = []
for s in steps:
k = s["kind"]View on GitHub (pinned to 95e1c3d0ab)