calesthio/OpenMontage · error · ValueError

Selected face_id {selected_id!r} was not returned by identif

Error message

Selected face_id {selected_id!r} was not returned by identify_face

What it means

Raised by KlingLipSyncTool._selected_face_record when the face_id the user selected (via face_choose or top-level face_id) does not match any face returned by the identify_face call the tool just made. The advanced lip-sync payload needs the detected face's timing (start_time/end_time), so the id must exist in the fresh detection results.

Source

Thrown at tools/avatar/kling_lip_sync.py:493

                width = value.get("width") or value.get("w")
                height = value.get("height") or value.get("h")
                if width is not None and height is not None:
                    return max(float(width), 0.0) * max(float(height), 0.0)
        width = face.get("width") or face.get("w")
        height = face.get("height") or face.get("h")
        if width is not None and height is not None:
            return max(float(width), 0.0) * max(float(height), 0.0)
        return 0.0

    @staticmethod
    def _selected_face_record(
        faces: list[dict[str, Any]], face_choose: list[dict[str, Any]]
    ) -> dict[str, Any]:
        selected_id = str(face_choose[0].get("face_id") or "")
        for face in faces:
            if str(face.get("face_id") or face.get("id") or "") == selected_id:
                return face
        raise ValueError(f"Selected face_id {selected_id!r} was not returned by identify_face")

    def _apply_face_timing_defaults(
        self, inputs: dict[str, Any], face: dict[str, Any]
    ) -> None:
        face_start = int(face.get("start_time") or 0)
        face_end = int(face.get("end_time") or 0)
        face_choose = self._normalize_face_choose(inputs)
        face_item = face_choose[0] if face_choose else {}
        if inputs.get("sound_start_time") is None and face_item.get("sound_start_time") is None:
            inputs["sound_start_time"] = 0
        if inputs.get("sound_insert_time") is None and face_item.get("sound_insert_time") is None:
            inputs["sound_insert_time"] = face_start
        if inputs.get("sound_end_time") is not None or face_item.get("sound_end_time") is not None:
            return

        candidates: list[int] = []
        audio_duration = self._local_audio_duration_ms(inputs)
        if audio_duration:

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Run kling_official_face_identify on the same video id first, and use a face_id from that exact response
  2. Do not reuse face ids across runs or across different video uploads; re-identify after any re-upload
  3. If you selected by face_id from a previous response, verify the video input is byte-identical to the one used for detection

Example fix

# before
inputs = {"video_id": vid, "face_choose": ["face_1"]}  # stale id

# after
faces = identify_face(video_id=vid)
inputs = {"video_id": vid, "face_choose": [faces["faces"][0]["face_id"]]}
Defensive patterns

Strategy: validation

Validate before calling

faces = identify_face(video_id=vid)["faces"]
valid_ids = {str(f.get("face_id") or f.get("id")) for f in faces}
chosen = [str(c["face_id"]) for c in normalize_face_choose(inputs)]
if not set(chosen) <= valid_ids:
    raise ValueError(f"stale face ids {set(chosen) - valid_ids}; re-run identify_face")

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "was not returned by identify_face" in str(e):
        faces = identify_face(video_id=inputs["video_id"])["faces"]
        inputs["face_choose"] = [{"face_id": faces[0]["face_id"]}]
        return tool.run(inputs)
    raise

Prevention

When it happens

Trigger: Calling advanced lip-sync with a face_id from an earlier run or from a different video; stale face ids after the source video was re-uploaded (media ids change per upload); case/format mismatch such as passing an int id where detection returned a string (str() comparison handles this, but a genuinely different value fails).

Common situations: Caching face ids between sessions, editing the video between identify and lip-sync steps, or hand-typing a face id. Also occurs when identify_face is skipped and an invented id like "face_1" is passed.

Related errors


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