calesthio/OpenMontage · error · ValueError

Kling identify_face requires video_url or video_id; local…

Error message

Kling identify_face requires video_url or video_id; local video paths cannot be silently uploaded.

What it means

ValueError from _build_identify_request when video_path is supplied but neither video_url nor video_id is. This is a deliberate guard: identify-face requires a Kling-hosted video, and the tool refuses to silently upload a local file (which would spend quota and have side effects the caller did not ask for). The message tells the developer the upload must be explicit.

Solutions

  1. Upload the local video first (Kling upload/video-creation endpoint or a tool that returns video_id/video_url), then pass video_id or video_url.
  2. Or host the file at a public URL and pass video_url.
  3. Do not pass video_path together with the expectation of implicit upload — it will always fail fast.

Example fix

// before
result = tool.run({"operation": "identify_face", "video_path": "clip.mp4"})

// after
video_id = kling_upload("clip.mp4")  # explicit upload step
result = tool.run({"operation": "identify_face", "video_id": video_id})
Defensive patterns

Strategy: validation

Validate before calling

if inputs.get("video_path") and not (inputs.get("video_url") or inputs.get("video_id")):
    inputs["video_id"] = upload_video(inputs["video_path"])  # explicit upload

Prevention

When it happens

Trigger: Calling kling_lip_sync operation='identify_face' (or the auto flow) with only video_path pointing to a local file.

Common situations: Pipeline renders a local video then immediately tries lip-sync; developer assumes the tool auto-uploads like some other tools do.

Related errors


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

Appendix: source

Thrown at tools/avatar/kling_lip_sync.py:350

                "output": str(paths[0]),
                "output_path": str(paths[0]),
                "video_paths": [str(path) for path in paths],
                "format": "mp4",
                "cost_estimate_confidence": "low",
                "cost_estimate_basis": "Conservative estimate pending official account-usage reconciliation.",
                **self._account_usage_result(inputs, client),
                **self._callback_result_data(inputs, task_id),
                **probed,
            },
            artifacts=[str(path) for path in paths],
            cost_usd=self.estimate_cost(inputs),
            duration_seconds=round(time.time() - start, 2),
            model="kling-official-lip-sync",
        )

    def _build_identify_request(self, inputs: dict[str, Any]) -> dict[str, Any]:
        if inputs.get("video_path") and not (inputs.get("video_url") or inputs.get("video_id")):
            raise ValueError("Kling identify_face requires video_url or video_id; local video paths cannot be silently uploaded.")
        payload: dict[str, Any] = {}
        if inputs.get("video_id"):
            payload["video_id"] = str(inputs["video_id"])
        if inputs.get("video_url"):
            payload["video_url"] = str(inputs["video_url"])
        if not payload:
            raise ValueError("Kling identify_face requires video_id or video_url")
        return {
            "path": "/v1/videos/identify-face",
            "payload": payload,
            "operation": "identify_face",
        }

    def _build_advanced_request(self, inputs: dict[str, Any]) -> dict[str, Any]:
        session_id = str(inputs.get("session_id") or "").strip()
        if not session_id:
            raise ValueError("advanced_lip_sync requires session_id")
        face_choose = self._normalize_face_choose(inputs)

View on GitHub (pinned to 95e1c3d0ab)