calesthio/OpenMontage · error · ValueError
Kling lip-sync response contained no videos
Error message
Kling lip-sync response contained no videos
What it means
Raised by KlingLipSyncTool._download_videos when the Kling task response's outputs list is empty (or falsy). The task reached the download stage but returned zero video entries — typically a failed or partially-failed generation that still reported completion, or an unexpected response shape.
Source
Thrown at tools/avatar/kling_lip_sync.py:658
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)
suffix = extension_from_url(url, ".mp4")
output_path = numbered_output_path(output_path_with_suffix(base_path, suffix), index, suffix)
client.download(url, output_path)
paths.append(output_path)
return paths
@staticmethod
def _output_url(item: dict[str, Any]) -> str:
url = item.get("url") or item.get("video_url") or item.get("resource_url")
if url:
return str(url)
resource = item.get("resource") or {}
if isinstance(resource, dict) and resource.get("url"):
return str(resource["url"])View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Retry the task once — transient upstream failures sometimes produce empty outputs
- Inspect the full task response (status, error message fields) before the tool's download step to see the real Kling-side status/error
- Check that the audio meets Kling constraints (>=2s crop, valid format) and the face selection was valid
- If it persists, capture the raw response and report as a tool/API issue
Defensive patterns
Strategy: retry
Validate before calling
resp = client.wait_for_task(task_id)
if not resp.get("outputs"):
log.warning("empty outputs; task status=%s msg=%s", resp.get("status"), resp.get("msg")) Try / catch
try:
paths = tool._download_videos(client, outputs, inputs)
except ValueError as e:
if "no videos" in str(e) and attempt < MAX_RETRIES:
outputs = client.wait_for_task(task_id, force_refresh=True).get("outputs", [])
continue # retry once with fresh task state
raise Prevention
- Verify task status and any error/message fields before downloading
- Retry once — transient empty outputs happen
- Validate audio length and face selection up front to avoid Kling-side rejections
When it happens
Trigger: Polling a Kling advanced/full lip-sync task whose final status contains no outputs array entries; a callback-driven flow where the callback payload lacked video data; upstream API change renaming the outputs field so the tool sees [].
Common situations: Kling-side generation failure reported as success; content-policy or audio-length rejections that produce no video; intermittent API quirks; version drift in the Kling response schema.
Related errors
- Kling avatar response contained no videos
- Kling identify-face response missing data.session_id: {data}
- Kling identify-face response face list is not a list
- Kling lip-sync response item contained no downloadable URL:
- Kling TTS response contained no audios
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/7a56ced8c46c4702.
Report an issue: GitHub.