calesthio/OpenMontage · error · ValueError

Kling TTS response contained no audios

Error message

Kling TTS response contained no audios

What it means

Raised as ValueError by _download_audios when the outputs list from the create response or polling is empty (falsy). The task nominally succeeded and returned an audios array, but it contains zero entries, so there is nothing to download.

Source

Thrown at tools/audio/kling_tts.py:283

            )

        task_id = client.create_classic_task(request["path"], request["payload"])
        return task_id, client.poll_classic(
            request["path"],
            task_id,
            "audios",
            timeout_seconds=int(inputs.get("timeout_seconds", 300)),
            poll_interval=float(inputs.get("poll_interval", 3.0)),
        )

    def _download_audios(
        self,
        client: KlingClient,
        outputs: list[dict[str, Any]],
        inputs: dict[str, Any],
    ) -> list[Path]:
        if not outputs:
            raise ValueError("Kling TTS response contained no audios")
        base_path = Path(inputs.get("output_path", "kling_tts.mp3"))
        paths: list[Path] = []
        for index, item in enumerate(outputs):
            url = self._output_url(item)
            suffix = extension_from_url(url, ".mp3")
            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("audio_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. Log the raw outputs value and the last poll response to distinguish 'empty from API' vs 'extraction miss'
  2. Retry the create — empty-audio success is usually transient
  3. If poll_classic extracts by key, verify the key name matches the current response shape
Defensive patterns

Strategy: validation

Validate before calling

if not outputs:
    raise ValueError("kling returned zero audios; retry the create call")

Type guard

def has_audios(outputs: Any) -> bool:
    return isinstance(outputs, list) and len(outputs) > 0

Try / catch

try:
    result = kling_tts_tool.execute(inputs)
except ValueError as e:
    if "no audios" in str(e):
        result = kling_tts_tool.execute(inputs)  # one retry: empty-success is transient
    else:
        raise

Prevention

When it happens

Trigger: poll_classic returns an empty 'audios' list on success; synchronous create returns task_result.audios: []; shape change yielding an empty container instead of null.

Common situations: Upstream bug or partial success returning an empty array; polling helper that returns a default empty list when its extraction key misses; silent moderation drop of all audio segments.

Related errors


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