{"record":{"id":"1da43e6bcd292485","repo":"calesthio/OpenMontage","slug":"conflicting-key-values-between-top-level-input-a","errorCode":null,"errorMessage":"Conflicting {key} values between top-level input and face_choose[0]","messagePattern":"Conflicting (.+?) values between top-level input and face_choose\\[0\\]","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/avatar/kling_lip_sync.py","lineNumber":540,"sourceCode":"    def _local_audio_duration_ms(inputs: dict[str, Any]) -> int | None:\n        sound_path = inputs.get(\"sound_file_path\") or inputs.get(\"audio_path\")\n        if not sound_path:\n            return None\n        path = Path(sound_path)\n        if not path.is_file():\n            return None\n        seconds = probe_output(path).get(\"duration_seconds\")\n        if not seconds:\n            return None\n        return int(round(float(seconds) * 1000))\n\n    @staticmethod\n    def _copy_timing_fields(inputs: dict[str, Any], face_item: dict[str, Any]) -> None:\n        for key, default in ((\"sound_start_time\", 0), (\"sound_insert_time\", 0)):\n            nested = face_item.get(key)\n            top_level = inputs.get(key)\n            if nested is not None and top_level is not None and int(nested) != int(top_level):\n                raise ValueError(\n                    f\"Conflicting {key} values between top-level input and face_choose[0]\"\n                )\n            value = nested if nested is not None else top_level\n            if value is None:\n                value = default\n            face_item[key] = int(value)\n\n        nested_end = face_item.get(\"sound_end_time\")\n        top_level_end = inputs.get(\"sound_end_time\")\n        if (\n            nested_end is not None\n            and top_level_end is not None\n            and int(nested_end) != int(top_level_end)\n        ):\n            raise ValueError(\n                \"Conflicting sound_end_time values between top-level input and face_choose[0]\"\n            )\n        sound_end = nested_end if nested_end is not None else top_level_end","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/avatar/kling_lip_sync.py#L522-L558","documentation":"Raised by KlingLipSyncTool._copy_timing_fields when sound_start_time or sound_insert_time is set both at the top level of the inputs and inside face_choose[0], and the two values differ after int() coercion. The tool refuses to guess which value wins, so it fails fast rather than silently picking one.","triggerScenarios":"advanced_lip_sync with e.g. inputs['sound_insert_time']=1000 plus face_choose=[{'face_id': 'f1', 'sound_insert_time': 2000}] — 1000 != 2000 raises. Note the error names the concrete key (sound_start_time or sound_insert_time) in {key}.","commonSituations":"Copying a working top-level payload and later adding per-face overrides without removing the top-level copy; agent pipelines merging user settings with template defaults at both levels.","solutions":["Keep timing values in exactly one place: either top-level or face_choose[0], not both","If both must exist, make them equal so the conflict check passes","Prefer per-face values in face_choose when syncing multiple faces, and delete the top-level keys"],"exampleFix":"# before\ninputs = {\"sound_insert_time\": 1000, \"face_choose\": [{\"face_id\": \"f1\", \"sound_insert_time\": 2000}]}\n\n# after\ninputs = {\"face_choose\": [{\"face_id\": \"f1\", \"sound_insert_time\": 2000}]}","handlingStrategy":"validation","validationCode":"face_item = (inputs.get(\"face_choose\") or [{}])[0]\nfor key in (\"sound_start_time\", \"sound_insert_time\"):\n    nested, top = face_item.get(key), inputs.get(key)\n    if nested is not None and top is not None and int(nested) != int(top):\n        raise ValueError(f\"conflicting {key}: pick one scope\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep timing values in exactly one scope (top-level or face_choose)","Build payloads from a single spec object instead of merging layers","Assert single-scope timing in a payload validator before invoking the tool"],"tags":["kling","lip-sync","timing","conflicting-inputs"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}