calesthio/OpenMontage · error · ValueError

Kling identify_face requires video_url or video_id; local vi

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.

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)

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.