{"record":{"id":"a3c42febc6cfb23e","repo":"calesthio/OpenMontage","slug":"unsupported-kling-lip-sync-operation-operation","errorCode":null,"errorMessage":"Unsupported Kling lip-sync operation: {operation}","messagePattern":"Unsupported Kling lip-sync operation: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/avatar/kling_lip_sync.py","lineNumber":241,"sourceCode":"                        artifacts=[str(artifact_path)],\n                        error=\"Multiple faces detected. Pass face_id/face_choose or set auto_select_face=True.\",\n                        cost_usd=self.estimate_cost({\"operation\": \"identify_face\"}),\n                        duration_seconds=round(time.time() - start, 2),\n                        model=\"kling-official-lip-sync\",\n                    )\n                merged = {**inputs, \"session_id\": identify[\"session_id\"], \"face_choose\": face_choose}\n                selected_face = self._selected_face_record(identify[\"faces\"], face_choose)\n                self._apply_face_timing_defaults(merged, selected_face)\n                request = self._build_advanced_request(merged)\n                result = self._run_advanced_lip_sync(client, merged, request, start)\n                result.data[\"faces_artifact_path\"] = str(artifact_path)\n                result.data[\"face_selection\"] = selection\n                result.artifacts.append(str(artifact_path))\n                return result\n            if operation == \"advanced_lip_sync\":\n                request = self._build_advanced_request(inputs)\n                return self._run_advanced_lip_sync(client, inputs, request, start)\n            raise ValueError(f\"Unsupported Kling lip-sync operation: {operation}\")\n        except (KlingAPIError, TimeoutError, ValueError, KeyError, FileNotFoundError) as exc:\n            data: dict[str, Any] = {\"provider\": self.provider}\n            if isinstance(exc, KlingAPIError):\n                data.update(\n                    {\n                        \"error_code\": exc.code,\n                        \"request_id\": exc.request_id,\n                        \"http_status\": exc.http_status,\n                        \"account_usage_diagnostic\": account_usage_hint_for_error(exc),\n                    }\n                )\n            return ToolResult(success=False, data=data, error=f\"Kling official lip-sync failed: {exc}\")\n        except Exception as exc:\n            return ToolResult(success=False, data={\"provider\": self.provider}, error=f\"Kling official lip-sync failed: {exc}\")\n\n    def _identify_faces(self, client: KlingClient, inputs: dict[str, Any]) -> dict[str, Any]:\n        request = self._build_identify_request(inputs)\n        data = client.post(request[\"path\"], request[\"payload\"])","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/avatar/kling_lip_sync.py#L223-L259","documentation":"ValueError from the Kling lip-sync tool dispatcher when the operation input matches neither 'identify_face', 'advanced_lip_sync', nor the auto/combined paths. The operation routes to completely different API endpoints (/v1/videos/identify-face vs /v1/videos/advanced-lip-sync), so an unknown value cannot be guessed. The error is caught by the tool's own except clause and returned as a failed ToolResult, not raised to the caller.","triggerScenarios":"Passing operation='lip_sync', 'basic', 'sync', or any typo like 'identify-face' (hyphen instead of underscore) to kling_lip_sync.","commonSituations":"Operation names copied from Kling's raw API docs (hyphenated) instead of this tool's snake_case convention; version upgrade renaming operations; LLM agents guessing operation names.","solutions":["Set operation to one of the supported values: 'identify_face' or 'advanced_lip_sync' (check the dispatch block above line 241 for the full set including auto flows).","Use underscores, not hyphens: 'identify_face', not 'identify-face'.","Check ToolResult.success and ToolResult.error rather than expecting an exception — this failure returns a result object."],"exampleFix":"// before\nresult = tool.run({\"operation\": \"lip-sync\", \"video_url\": v, \"audio_path\": a})\n\n// after\nresult = tool.run({\"operation\": \"advanced_lip_sync\", \"video_url\": v, \"audio_path\": a})","handlingStrategy":"validation","validationCode":"SUPPORTED_OPS = {\"identify_face\", \"advanced_lip_sync\"}  # plus auto flows per dispatch\noperation = str(inputs.get(\"operation\") or \"\").strip()\nassert operation in SUPPORTED_OPS, f\"unsupported operation: {operation}\"","typeGuard":"def is_supported_operation(op: str) -> bool:\n    return op in {\"identify_face\", \"advanced_lip_sync\"}","tryCatchPattern":"result = tool.run(inputs)\nif not result.success and \"Unsupported Kling lip-sync operation\" in (result.error or \"\"):\n    # fix the operation name and re-run; this is a result, not an exception","preventionTips":["Use snake_case operation names matching the tool dispatcher, not Kling's hyphenated API paths","Check ToolResult.success rather than expecting exceptions from this tool"],"tags":["kling","lip-sync","enum-validation","routing"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}