calesthio/OpenMontage · error · ValueError

Kling video response contained no downloadable URL: {outputs

Error message

Kling video response contained no downloadable URL: {outputs}

What it means

Raised by `_first_output_url(outputs)` after it iterated the entire outputs list and every item failed the `_output_url` extraction (which checks `url`, `video_url`, `resource_url`, then nested `resource.url`). It is the aggregate version of the per-item 'no downloadable URL' error: the whole list is embedded in the message so the developer can audit every response item at once.

Source

Thrown at tools/video/kling_official_video.py:704

            if inputs.get(key):
                count += 1
        return count

    @staticmethod
    def _prompt(inputs: dict[str, Any]) -> str:
        prompt = str(inputs.get("prompt") or "").strip()
        if not prompt:
            raise ValueError("prompt is required")
        return prompt

    @staticmethod
    def _first_output_url(outputs: list[dict[str, Any]]) -> str:
        for item in outputs:
            try:
                return KlingOfficialVideo._output_url(item)
            except ValueError:
                continue
        raise ValueError(f"Kling video response contained no downloadable URL: {outputs}")

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Dump the full `outputs` list from the error message and locate the real URL field name
  2. Extend `_output_url` with the new field — fixing it once fixes both this and the per-item error
  3. Ensure only completed, asset-bearing works are passed as outputs
  4. If URLs were present but expired, regenerate: Kling remote URLs are time-limited
Defensive patterns

Strategy: type-guard

Validate before calling

urls = [u for u in (extract_output_url(i) for i in outputs) if u]
if not urls:
    raise ValueError(f"no downloadable URLs in outputs: {outputs}")
first = urls[0]

Type guard

def any_downloadable(outputs: list[dict]) -> bool:
    return any(
        i.get("url") or i.get("video_url") or i.get("resource_url")
        or (isinstance(i.get("resource"), dict) and i["resource"].get("url"))
        for i in outputs
    )

Try / catch

try:
    url = KlingOfficialVideo._first_output_url(outputs)
except ValueError as e:
    logger.error("response shape drift: %s", e)
    raise

Prevention

When it happens

Trigger: Same conditions as the per-item error, but affecting all outputs: a renamed URL field across the whole response, outputs being non-final status objects, or a provider payload shape change; also hit when `outputs` contains items whose `resource` is not a dict.

Common situations: API contract drift after a Kling version bump; polling loops feeding unfiltered task lists; moderation-flagged generations that return success-shaped items without assets. Distinct from the per-item error in that `_first_output_url` (used where only one URL is needed) tolerates individual bad items and only fails when none work.

Related errors


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