calesthio/OpenMontage · error · ValueError
Cannot select face without face_id/id: {face}
Error message
Cannot select face without face_id/id: {face} What it means
Raised by KlingLipSyncTool._face_to_choice when the tool tries to convert a face record from identify_face into a selection choice but the record has neither face_id nor id. This happens on the automatic paths: exactly one detected face, or auto_select_face=True picking the largest face. The tool cannot tell Kling which face to animate without an identifier.
Source
Thrown at tools/avatar/kling_lip_sync.py:453
if not inputs.get("auto_select_face"):
return [], {
"selection_method": "requires_user_selection",
"selection_reason": "Multiple faces detected and auto_select_face was not enabled",
"face_count": len(faces),
}
selected = max(faces, key=self._face_area)
choice = [self._face_to_choice(selected)]
return choice, {
"selection_method": "auto_selected",
"selection_reason": "auto_select_face=True selected the largest detected face area",
"selected_face": choice,
}
@staticmethod
def _face_to_choice(face: dict[str, Any]) -> dict[str, Any]:
face_id = face.get("face_id") or face.get("id")
if not face_id:
raise ValueError(f"Cannot select face without face_id/id: {face}")
return {"face_id": str(face_id)}
@staticmethod
def _face_area(face: dict[str, Any]) -> float:
for key in ("bbox", "box"):
value = face.get(key)
if isinstance(value, list) and len(value) >= 4:
third = float(value[2])
fourth = float(value[3])
width_height_area = max(third, 0.0) * max(fourth, 0.0)
corner_width = third - float(value[0])
corner_height = fourth - float(value[1])
corner_area = (
corner_width * corner_height
if corner_width > 0 and corner_height > 0
else 0.0
)
if corner_area and width_height_area:View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Inspect the identify_face output for your video and pass explicit face_choose entries using whatever id field it actually returns, if any
- Re-run identify_face; if its schema truly lacks ids, this is a tool bug — report it with the raw face payload
- If mocking in tests, include face_id (or id) in every face record
Example fix
# before (mock faces without ids)
faces = [{"bbox": [10, 10, 100, 100]}]
# after
faces = [{"face_id": "face_1", "bbox": [10, 10, 100, 100]}] Defensive patterns
Strategy: validation
Validate before calling
faces = identify_face(video_id=vid)["faces"]
if not all(f.get("face_id") or f.get("id") for f in faces):
raise ValueError(f"identify_face returned id-less records: {faces}")
# safe to proceed with auto_select_face or single-face shortcut Type guard
def faces_have_ids(faces) -> bool:
return all(bool(f.get("face_id") or f.get("id")) for f in faces) Prevention
- Run identify_face first and assert every record carries face_id/id
- Pass explicit face_choose ids instead of relying on auto-selection when detection output looks unusual
- Report id-less detection payloads as a schema issue
When it happens
Trigger: Running kling_lip_sync on a video where identify_face returns face records whose id field is named something else (e.g. "faceid", "uuid") or is missing entirely. Triggered either via the single-face shortcut or via auto_select_face=True with multiple faces.
Common situations: A changed or unexpected identify_face response schema (upstream API version change), or a hand-crafted faces list passed in tests/mocks that omits the id key.
Related errors
- Kling identify-face response contained no faces
- Unsupported Kling lip-sync operation: {operation}
- Kling identify-face response missing data.session_id: {data}
- Kling identify-face response face list is not a list
- Kling identify_face requires video_url or video_id; local vi
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/aefd09ffb9855368.
Report an issue: GitHub.