calesthio/OpenMontage · error · ValueError

Kling avatar requires audio_id, sound_file, sound_file_url,

Error message

Kling avatar requires audio_id, sound_file, sound_file_url, sound_file_path, or audio_path

What it means

ValueError from KlingAvatarTool._copy_audio_input when no audio source is provided. Talking-avatar generation is audio-driven: Kling needs either a previously uploaded audio_id or a sound file (inline value sound_file, URL sound_file_url, or local path sound_file_path/audio_path). normalize_media_input returning falsy means none of the five accepted inputs was usable.

Source

Thrown at tools/avatar/kling_avatar.py:271

            "audio_source": audio_source,
        }

    @staticmethod
    def _copy_audio_input(inputs: dict[str, Any], payload: dict[str, Any]) -> dict[str, Any]:
        audio_id = str(inputs.get("audio_id") or "").strip()
        if audio_id:
            payload["audio_id"] = audio_id
            return {"type": "audio_id", "value": audio_id}

        sound_path = inputs.get("sound_file_path") or inputs.get("audio_path")
        sound_file = normalize_media_input(
            url=inputs.get("sound_file_url"),
            path=sound_path,
            value=inputs.get("sound_file"),
            label="Avatar audio file",
        )
        if not sound_file:
            raise ValueError("Kling avatar 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 avatar response contained no videos")
        base_path = Path(inputs.get("output_path", "kling_avatar.mp4"))
        paths: list[Path] = []
        for index, item in enumerate(outputs):
            url = self._output_url(item)

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Provide one of: audio_id (from a prior Kling audio upload), sound_file (inline bytes/base64), sound_file_url (public URL), sound_file_path, or audio_path (local file).
  2. Verify local audio files exist and are non-empty before the call.
  3. If using audio_id, confirm it came from a successful upload under the same API key.

Example fix

// before
result = tool.run({"image_path": "portrait.png"})  # no audio

// after
result = tool.run({
    "image_path": "portrait.png",
    "sound_file_path": "narration.mp3",
})
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
audio_ok = any([
    inputs.get("audio_id"),
    inputs.get("sound_file"),
    inputs.get("sound_file_url"),
    inputs.get("sound_file_path") and Path(inputs["sound_file_path"]).is_file(),
    inputs.get("audio_path") and Path(inputs["audio_path"]).is_file(),
])
assert audio_ok, "kling_avatar requires one audio source"

Prevention

When it happens

Trigger: Calling kling_avatar with an image but no audio inputs; passing sound_file_path to a file that does not exist; passing a sound_file_url that is empty or malformed.

Common situations: Forgetting the TTS step in the pipeline so no audio path exists; audio step wrote to a different filename; using audio_id from a different Kling account/app so the value is stale.

Related errors


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