calesthio/OpenMontage · error · ValueError
Kling lip-sync response item contained no downloadable URL:
Error message
Kling lip-sync response item contained no downloadable URL: {item} What it means
Raised by KlingLipSyncTool._output_url when a single output item contains no URL under any known key: url, video_url, resource_url, or resource.url. The item exists but has no downloadable location, so the tool cannot fetch the rendered video. The message embeds the offending item for diagnosis.
Source
Thrown at tools/avatar/kling_lip_sync.py:677
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"])
raise ValueError(f"Kling lip-sync response item contained no downloadable URL: {item}")
@staticmethod
def _copy_common_task_fields(inputs: dict[str, Any], payload: dict[str, Any]) -> None:
callback_url = validate_callback_url(inputs.get("callback_url"))
if callback_url:
payload["callback_url"] = callback_url
if inputs.get("external_task_id"):
payload["external_task_id"] = inputs["external_task_id"]
@staticmethod
def _callback_result_data(inputs: dict[str, Any], task_id: str) -> dict[str, Any]:
callback_url = inputs.get("callback_url")
if not callback_url:
return {}
return {
"callback_url": str(callback_url),
"callback_requested": True,
"polling_used": True,View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Log the embedded item dict — it usually reveals the actual field name or a pending/expired status
- Wait for the task to be fully complete (not merely 'succeeded' at task level) before downloading, then retry
- If a new field name appears (e.g. 'download_url'), map it into item['url'] in your wrapper before the tool reads it, or patch _output_url and report upstream
Defensive patterns
Strategy: try-catch
Validate before calling
def item_has_url(item) -> bool:
if item.get("url") or item.get("video_url") or item.get("resource_url"):
return True
r = item.get("resource")
return isinstance(r, dict) and bool(r.get("url"))
bad = [i for i in outputs if not item_has_url(i)]
if bad:
log.warning("output items without URLs: %s", bad) Type guard
def item_has_url(item) -> bool:
if item.get("url") or item.get("video_url") or item.get("resource_url"):
return True
r = item.get("resource")
return isinstance(r, dict) and bool(r.get("url")) Try / catch
try:
url = extract_output_url(item)
except ValueError:
log.warning("no URL in item; waiting and re-polling task: %s", item)
outputs = client.wait_for_task(task_id, force_refresh=True).get("outputs", [])
# re-attempt extraction once Prevention
- Download promptly after task completion before CDN links expire
- Log raw output items on failure — they reveal renamed fields or pending status
- Map unknown URL fields to item['url'] in your wrapper if the upstream schema drifts
When it happens
Trigger: An outputs entry that only carries metadata (id, status, thumbnails) because the video asset is still processing or was purged; an upstream schema change introducing a new URL field name the tool does not know; an item whose resource is not a dict.
Common situations: Downloading too early after task completion; expired CDN links from a delayed download; Kling API version drift.
Related errors
- Kling identify-face response missing data.session_id: {data}
- Kling identify-face response face list is not a list
- Kling lip-sync response contained no videos
- Kling TTS response contained no audios
- Kling TTS response item contained no downloadable URL: {item
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/f0352587d6a95d42.
Report an issue: GitHub.