calesthio/OpenMontage · error · ValueError
duration must be an integer from 4 to {max_seconds} or -1
Error message
duration must be an integer from 4 to {max_seconds} or -1 What it means
Raised by _normalize_duration when the duration value cannot be accepted as an integer in [4, max_seconds] or the -1 'auto' marker. Beyond non-integers, it deliberately rejects values like '5s', ' 5 ', and 5.5 whose string form does not round-trip to the parsed integer — a strictness guard against silent coercion. max_seconds defaults to 15 (the code path that formats the message).
Source
Thrown at tools/video/seedance_ark.py:933
or os.environ.get("ARK_SEEDANCE_MODEL")
or self.MODEL_IDS[variant]
)
if not model or any(char.isspace() for char in model):
raise ValueError("model must be a non-empty Ark Model/Endpoint ID")
for known_variant, known_model in self.MODEL_IDS.items():
if model == known_model:
return model, known_variant
# Endpoint IDs and future model IDs can have account-specific pricing.
# Keep the caller's requested model, but never pretend its price is the
# public price of model_variant.
return model, None
@staticmethod
def _normalize_duration(value: Any, max_seconds: int = 15) -> int:
if value == "auto":
return -1
if isinstance(value, bool):
raise ValueError(
f"duration must be an integer from 4 to {max_seconds} or -1"
)
try:
duration = int(value)
except (TypeError, ValueError) as exc:
raise ValueError(
f"duration must be an integer from 4 to {max_seconds} or -1"
) from exc
if str(value).strip() not in {str(duration), "auto"}:
raise ValueError(
f"duration must be an integer from 4 to {max_seconds} or -1"
)
if duration != -1 and not 4 <= duration <= max_seconds:
raise ValueError(f"duration must be between 4 and {max_seconds} or -1")
return duration
@staticmethod
def _single_image_refs(inputs: dict[str, Any]) -> list[Any]:View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Pass duration as a plain integer 4..15 (or -1 / 'auto')
- Strip unit suffixes and round before calling: duration=int(str(value).strip().rstrip('s'))
- Validate durations at the config/UI boundary so '5s'-style strings never reach the tool
Example fix
# before
inputs = {"duration": "10s"}
# after
inputs = {"duration": 10} Defensive patterns
Strategy: validation
Validate before calling
def normalize_duration(value, max_seconds=15):
if value in (-1, "auto", "-1"):
return -1
if isinstance(value, bool):
raise ValueError("duration must be an int 4..%d or -1" % max_seconds)
try:
d = int(str(value).strip().rstrip("s").strip())
except ValueError:
raise ValueError("duration must be an int 4..%d or -1" % max_seconds)
if not (4 <= d <= max_seconds or d == -1):
raise ValueError("duration must be an int 4..%d or -1" % max_seconds)
return d
inputs["duration"] = normalize_duration(inputs.get("duration")) Type guard
def is_valid_duration(value, max_seconds=15) -> bool:
if value in (-1, "auto"): return True
if isinstance(value, bool): return False
try:
d = int(value)
except (TypeError, ValueError):
return False
return str(value).strip() in {str(d), "auto"} and (4 <= d <= max_seconds or d == -1) Prevention
- Send integers only; strip 's' suffixes at the UI boundary
- Reject float durations at config validation, not deep in the pipeline
When it happens
Trigger: duration='5s', duration=5.5, duration=' 5', duration=True (bools rejected before int coercion), or a non-numeric string; 'auto' and -1 are accepted, and '5' / 5 pass.
Common situations: Forwarding UI strings like '10s'; passing a float computed from a seconds calculation; boolean flags leaking into duration from config merges; unit confusion (frames vs seconds).
Related errors
- text_to_video does not accept reference media; use image_to_
- image_to_video requires exactly one reference image
- provide only one of end_image_url/end_image_path
- reference_to_video requires at least one image or video
- web_search is supported only for pure text input
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/85200f3b4d12dd17.
Report an issue: GitHub.