{"record":{"id":"735831d9adce4872","repo":"calesthio/OpenMontage","slug":"advanced-lip-sync-requires-sound-end-time","errorCode":null,"errorMessage":"advanced_lip_sync requires sound_end_time","messagePattern":"advanced_lip_sync requires sound_end_time","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/avatar/kling_lip_sync.py","lineNumber":560,"sourceCode":"                )\n            value = nested if nested is not None else top_level\n            if value is None:\n                value = default\n            face_item[key] = int(value)\n\n        nested_end = face_item.get(\"sound_end_time\")\n        top_level_end = inputs.get(\"sound_end_time\")\n        if (\n            nested_end is not None\n            and top_level_end is not None\n            and int(nested_end) != int(top_level_end)\n        ):\n            raise ValueError(\n                \"Conflicting sound_end_time values between top-level input and face_choose[0]\"\n            )\n        sound_end = nested_end if nested_end is not None else top_level_end\n        if sound_end is None:\n            raise ValueError(\"advanced_lip_sync requires sound_end_time\")\n        face_item[\"sound_end_time\"] = int(sound_end)\n        if face_item[\"sound_end_time\"] - face_item[\"sound_start_time\"] < 2000:\n            raise ValueError(\"advanced_lip_sync requires at least 2000ms of cropped audio\")\n\n        for key in (\"sound_volume\", \"original_audio_volume\"):\n            nested = face_item.get(key)\n            top_level = inputs.get(key)\n            if nested is not None and top_level is not None and float(nested) != float(top_level):\n                raise ValueError(\n                    f\"Conflicting {key} values between top-level input and face_choose[0]\"\n                )\n            value = nested if nested is not None else top_level\n            if value is not None:\n                face_item[key] = float(value)\n\n    @staticmethod\n    def _face_choose_result_metadata(\n        face_choose: list[dict[str, Any]],","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/avatar/kling_lip_sync.py#L542-L578","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"# before\ninputs = {\"video_id\": vid, \"face_choose\": [{\"face_id\": \"f1\"}], \"lip_sync_mode\": \"advanced\"}\n\n# after\ninputs = {\"video_id\": vid, \"face_choose\": [{\"face_id\": \"f1\", \"sound_end_time\": 6000}], \"lip_sync_mode\": \"advanced\"}","handlingStrategy":"validation","validationCode":"if mode == \"advanced\":\n    face_item = (inputs.get(\"face_choose\") or [{}])[0]\n    if inputs.get(\"sound_end_time\") is None and face_item.get(\"sound_end_time\") is None:\n        raise ValueError(\"advanced_lip_sync needs explicit sound_end_time\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["kling","lip-sync","timing","required-field"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}