calesthio/OpenMontage · error · ValueError
Conflicting {key} values between top-level input and face_ch
Error message
Conflicting {key} values between top-level input and face_choose[0] What it means
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.
Source
Thrown at tools/avatar/kling_lip_sync.py:540
def _local_audio_duration_ms(inputs: dict[str, Any]) -> int | None:
sound_path = inputs.get("sound_file_path") or inputs.get("audio_path")
if not sound_path:
return None
path = Path(sound_path)
if not path.is_file():
return None
seconds = probe_output(path).get("duration_seconds")
if not seconds:
return None
return int(round(float(seconds) * 1000))
@staticmethod
def _copy_timing_fields(inputs: dict[str, Any], face_item: dict[str, Any]) -> None:
for key, default in (("sound_start_time", 0), ("sound_insert_time", 0)):
nested = face_item.get(key)
top_level = inputs.get(key)
if nested is not None and top_level is not None and int(nested) != int(top_level):
raise ValueError(
f"Conflicting {key} values between top-level input and face_choose[0]"
)
value = nested if nested is not None else top_level
if value is None:
value = default
face_item[key] = int(value)
nested_end = face_item.get("sound_end_time")
top_level_end = inputs.get("sound_end_time")
if (
nested_end is not None
and top_level_end is not None
and int(nested_end) != int(top_level_end)
):
raise ValueError(
"Conflicting sound_end_time values between top-level input and face_choose[0]"
)
sound_end = nested_end if nested_end is not None else top_level_endView on GitHub (pinned to 95e1c3d0ab)
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
Example fix
# before
inputs = {"sound_insert_time": 1000, "face_choose": [{"face_id": "f1", "sound_insert_time": 2000}]}
# after
inputs = {"face_choose": [{"face_id": "f1", "sound_insert_time": 2000}]} Defensive patterns
Strategy: validation
Validate before calling
face_item = (inputs.get("face_choose") or [{}])[0]
for key in ("sound_start_time", "sound_insert_time"):
nested, top = face_item.get(key), inputs.get(key)
if nested is not None and top is not None and int(nested) != int(top):
raise ValueError(f"conflicting {key}: pick one scope") Prevention
- 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
When it happens
Trigger: 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}.
Common situations: 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.
Related errors
- Conflicting sound_end_time values between top-level input an
- full_lip_sync could not infer sound_end_time; provide it exp
- advanced_lip_sync requires sound_end_time
- advanced_lip_sync requires at least 2000ms of cropped audio
- Conflicting audio input in face_choose[0]; provide audio_id
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/1da43e6bcd292485.
Report an issue: GitHub.