calesthio/OpenMontage · error · ValueError

Kling identify-face response face list is not a list

Error message

Kling identify-face response face list is not a list

What it means

ValueError from _identify_faces when the face data field it finds is not a JSON list. The code tolerates five key names (face_data, faces, face_list, face_infos, faces_info); whichever matched first held a dict, string, or null-adjacent value instead of an array. This is a response-shape problem, not a user-input problem — Kling returned face data in an object wrapper (e.g. {items: [...]}) this parser does not unwrap.

Source

Thrown at tools/avatar/kling_lip_sync.py:273

            return ToolResult(success=False, data={"provider": self.provider}, error=f"Kling official lip-sync failed: {exc}")

    def _identify_faces(self, client: KlingClient, inputs: dict[str, Any]) -> dict[str, Any]:
        request = self._build_identify_request(inputs)
        data = client.post(request["path"], request["payload"])
        payload = data.get("data") or {}
        session_id = payload.get("session_id")
        if not session_id:
            raise ValueError(f"Kling identify-face response missing data.session_id: {data}")
        faces = (
            payload.get("face_data")
            or payload.get("faces")
            or payload.get("face_list")
            or payload.get("face_infos")
            or payload.get("faces_info")
            or []
        )
        if not isinstance(faces, list):
            raise ValueError("Kling identify-face response face list is not a list")
        if not faces:
            raise ValueError("Kling identify-face response contained no faces")
        return {
            "session_id": str(session_id),
            "faces": faces,
            "raw_response": data,
            "request": request,
        }

    def _identify_result(self, inputs: dict[str, Any], identify: dict[str, Any], start: float) -> ToolResult:
        artifact_path = self._write_faces_artifact(inputs, identify)
        return ToolResult(
            success=True,
            data={
                "provider": self.provider,
                "model": "kling-official-lip-sync",
                "operation": "identify_face",
                "session_id": identify["session_id"],

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Look at the raw_response saved in the identify result/artifact to see the actual shape of the face field.
  2. Unwrap the wrapper in _identify_faces: if isinstance(faces, dict): faces = faces.get('items') or faces.get('list') or [].
  3. Pin the tool to the gateway endpoint version it was written against.

Example fix

// before
faces = payload.get("face_data") or payload.get("faces") or ... or []
if not isinstance(faces, list):
    raise ValueError("Kling identify-face response face list is not a list")

// after
faces = payload.get("face_data") or payload.get("faces") or ... or []
if isinstance(faces, dict):
    faces = faces.get("items") or faces.get("list") or []
if not isinstance(faces, list):
    raise ValueError("Kling identify-face response face list is not a list")
Defensive patterns

Strategy: type-guard

Validate before calling

faces = payload.get("face_data") or payload.get("faces") or payload.get("face_list") \
    or payload.get("face_infos") or payload.get("faces_info") or []
if isinstance(faces, dict):
    faces = faces.get("items") or faces.get("list") or []

Type guard

def is_face_list(faces: object) -> bool:
    return isinstance(faces, list) and all(isinstance(f, (dict, str)) for f in faces)

Try / catch

if not is_face_list(faces):
    log.error("unexpected face payload shape: %r", faces)
    raise ValueError("Kling identify-face response face list is not a list")

Prevention

When it happens

Trigger: Gateway returning faces wrapped as {'faces': {'items': [...]}} or a pagination object; a 'faces' key holding a count or status string that truthy-checks past the or-chain.

Common situations: Kling API version differences between the international and Chinese endpoints; aggregator proxies reshaping responses.

Related errors


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