calesthio/OpenMontage · error · ValueError
advanced_lip_sync requires sound_end_time
Error message
advanced_lip_sync requires sound_end_time
What it means
Raised by KlingLipSyncTool._copy_timing_fields on the advanced lip-sync path when sound_end_time is absent from both the top-level inputs and face_choose[0]. Unlike full lip-sync (which infers it, see error 143), the advanced path requires an explicit crop end — there is no inference.
Source
Thrown at tools/avatar/kling_lip_sync.py:560
)
value = nested if nested is not None else top_level
if value is None:
value = default
face_item[key] = int(value)
nested_end = face_item.get("sound_end_time")
top_level_end = inputs.get("sound_end_time")
if (
nested_end is not None
and top_level_end is not None
and int(nested_end) != int(top_level_end)
):
raise ValueError(
"Conflicting sound_end_time values between top-level input and face_choose[0]"
)
sound_end = nested_end if nested_end is not None else top_level_end
if sound_end is None:
raise ValueError("advanced_lip_sync requires sound_end_time")
face_item["sound_end_time"] = int(sound_end)
if face_item["sound_end_time"] - face_item["sound_start_time"] < 2000:
raise ValueError("advanced_lip_sync requires at least 2000ms of cropped audio")
for key in ("sound_volume", "original_audio_volume"):
nested = face_item.get(key)
top_level = inputs.get(key)
if nested is not None and top_level is not None and float(nested) != float(top_level):
raise ValueError(
f"Conflicting {key} values between top-level input and face_choose[0]"
)
value = nested if nested is not None else top_level
if value is not None:
face_item[key] = float(value)
@staticmethod
def _face_choose_result_metadata(
face_choose: list[dict[str, Any]],View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Add sound_end_time (ms) to the top-level inputs or to face_choose[0]
- If you intended automatic inference, use full_lip_sync instead of advanced_lip_sync
- Remember the value must be at least sound_start_time + 2000 (see error 147)
Example fix
# before
inputs = {"video_id": vid, "face_choose": [{"face_id": "f1"}], "lip_sync_mode": "advanced"}
# after
inputs = {"video_id": vid, "face_choose": [{"face_id": "f1", "sound_end_time": 6000}], "lip_sync_mode": "advanced"} Defensive patterns
Strategy: validation
Validate before calling
if mode == "advanced":
face_item = (inputs.get("face_choose") or [{}])[0]
if inputs.get("sound_end_time") is None and face_item.get("sound_end_time") is None:
raise ValueError("advanced_lip_sync needs explicit sound_end_time") Prevention
- Remember advanced mode has no inference — full mode does
- Include sound_end_time in every advanced-lip-sync payload template
- Compute it from your audio duration during payload construction
When it happens
Trigger: Calling advanced_lip_sync (multi-face / per-face timing mode) with only sound_insert_time or a bare face_choose list of face ids and no sound_end_time anywhere.
Common situations: Switching a payload from full_lip_sync to advanced_lip_sync and assuming the same inference applies; passing only face ids as strings (which carry no timing) into face_choose.
Related errors
- Kling identify_face requires video_id or video_url
- advanced_lip_sync requires session_id
- advanced_lip_sync requires face_choose or face_id
- face_choose items must include face_id
- full_lip_sync could not infer sound_end_time; provide it exp
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/735831d9adce4872.
Report an issue: GitHub.