calesthio/OpenMontage · error · ValueError

Kling video response contained no videos

Error message

Kling video response contained no videos

What it means

Raised in `_download_videos` when the `outputs` list passed to it is empty. The tool has a task response it believes completed, but zero downloadable video objects came back, so there is nothing to save to `output_path`. This guards the download loop from iterating over nothing and returning an empty paths list that downstream stages would misinterpret as success.

Source

Thrown at tools/video/kling_official_video.py:602

        for item in inputs.get("video_list") or []:
            if not isinstance(item, dict):
                raise ValueError("video_list items must be objects")
            add_video(item, "video_list")
        if inputs.get("reference_video_url"):
            add_video({"video_url": inputs["reference_video_url"]}, "reference_video_url")
        for url in inputs.get("video_urls") or []:
            add_video({"video_url": url}, "video_urls")
        return video_list, references_used

    def _download_videos(
        self,
        client: KlingClient,
        outputs: list[dict[str, Any]],
        inputs: dict[str, Any],
    ) -> list[Path]:
        if not outputs:
            raise ValueError("Kling video response contained no videos")
        base_path = Path(inputs.get("output_path", "kling_official_video.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

  1. Inspect the raw task response (`task_id`, status, and the full JSON) to see which field holds the videos — the extractor may be looking at the wrong key after an API change
  2. Re-submit the generation: if the remote URLs expired, the task must be regenerated since Kling does not re-issue expired artifacts
  3. If calling `_download_videos` yourself, guard with `if not outputs:` and re-query the task before failing
  4. Report as a provider/API-contract bug if the response genuinely has status=succeeded with no works
Defensive patterns

Strategy: validation

Validate before calling

outputs = task_result.get("works") or task_result.get("videos") or []
if not outputs:
    # re-query once before giving up
    task = client.query(task_id)
    outputs = task.get("works") or []
if not outputs:
    raise ValueError(f"task {task_id} returned no downloadable videos")

Try / catch

try:
    paths = tool._download_videos(client, outputs, inputs)
except ValueError as e:
    if "contained no videos" in str(e):
        log.warning("empty outputs for task; re-querying once")
        task = client.query(task_id)
        outputs = extract_outputs(task)
        if not outputs:
            raise
        paths = tool._download_videos(client, outputs, inputs)
    else:
        raise

Prevention

When it happens

Trigger: The Kling API returns a task result whose video list field is empty or missing (e.g. `works: []`); a caller passes `outputs=[]` directly; the response-parsing step extracted no items from an otherwise 'succeeded' task.

Common situations: Provider API changes that rename the output field so the extractor finds nothing; querying a task that succeeded but whose assets expired (24-hour Kling URL lifetime) and were stripped from the response; partial provider outages returning malformed payloads with a success status.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/d5237d93631d5a71. Report an issue: GitHub.