calesthio/OpenMontage · error · ValueError
advanced_lip_sync requires audio_id, sound_file, sound_file_
Error message
advanced_lip_sync requires audio_id, sound_file, sound_file_url, sound_file_path, or audio_path
What it means
Raised by KlingLipSyncTool._copy_audio_input as the final fallback: no audio source exists anywhere — no audio_id and normalize_media_input over sound_file/sound_file_url/sound_file_path/audio_path produced nothing. Lip-sync without audio is meaningless, so the tool refuses before calling Kling.
Source
Thrown at tools/avatar/kling_lip_sync.py:644
if top_level_sound_file != nested_sound_file:
raise ValueError(
"Conflicting audio input between top-level fields and face_choose[0]"
)
return {"type": "sound_file", "source": "face_choose[0]"}
if top_level_audio_id:
payload["audio_id"] = top_level_audio_id
return {"type": "audio_id", "value": top_level_audio_id}
sound_path = inputs.get("sound_file_path") or inputs.get("audio_path")
sound_file = normalize_media_input(
url=inputs.get("sound_file_url"),
path=sound_path,
value=inputs.get("sound_file"),
label="Lip-sync audio file",
)
if not sound_file:
raise ValueError("advanced_lip_sync requires audio_id, sound_file, sound_file_url, sound_file_path, or audio_path")
payload["sound_file"] = sound_file
return {
"type": "sound_file",
"source": inputs.get("sound_file_url") or sound_path or "inline",
}
def _download_videos(
self,
client: KlingClient,
outputs: list[dict[str, Any]],
inputs: dict[str, Any],
) -> list[Path]:
if not outputs:
raise ValueError("Kling lip-sync response contained no videos")
base_path = Path(inputs.get("output_path", "kling_lip_sync.mp4"))
paths: list[Path] = []
for index, item in enumerate(outputs):
url = self._output_url(item)View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Provide exactly one of: audio_id, sound_file, sound_file_url, sound_file_path, or audio_path
- Check for typos in the audio field names
- If using sound_file_path, verify the file exists before the call
Example fix
# before
inputs = {"video_id": vid, "face_choose": [{"face_id": "f1"}]}
# after
inputs = {"video_id": vid, "face_choose": [{"face_id": "f1", "sound_file_path": "/tmp/vo.mp3"}]} Defensive patterns
Strategy: validation
Validate before calling
has_audio = any([
str(inputs.get("audio_id") or "").strip(),
inputs.get("sound_file"),
inputs.get("sound_file_url"),
(inputs.get("sound_file_path") and __import__("pathlib").Path(inputs["sound_file_path"]).is_file()),
(inputs.get("audio_path") and __import__("pathlib").Path(inputs["audio_path"]).is_file()),
])
if not has_audio:
raise ValueError("no audio source for lip-sync") Type guard
def has_lip_sync_audio(inputs) -> bool:
return any(inputs.get(k) for k in ("audio_id", "sound_file", "sound_file_url", "sound_file_path", "audio_path")) Prevention
- Make audio a required field in your payload schema
- Verify the audio file path exists before calling
- Watch for typos like sound_filepath
When it happens
Trigger: Calling kling_lip_sync with only video_id/face_choose and every audio field absent, empty string, or None. Also when sound_file_path points at a non-existent path such that normalization yields falsy (with no URL/value to fall back on).
Common situations: Forgetting the voiceover in an automated pipeline; audio field named something else in the caller's dict (typo like sound_filepath); empty-string defaults from a config loader.
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
- advanced_lip_sync requires sound_end_time
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/1bd9fe09f27f8ee5.
Report an issue: GitHub.