nexu-io/open-design · error · ValueError
Participant {speaker} has conflicting transcript avatar hint
Error message
Participant {speaker} has conflicting transcript avatar hints: {participant['avatarKey']} and {message['avatar']}; set a config preset to override What it means
Thrown in build_spec() when a speaker has multiple transcript lines whose inline avatar hints disagree, and no config 'preset' override exists to pin a single avatar. Without a config preset the builder cannot know which hint wins, so it refuses rather than silently picking one.
Source
Thrown at skills/chat-motion-overlay/scripts/build_chat_overlay_spec.py:201
participant = {
"id": unique_slug(slugify(speaker), used_participant_ids),
"name": speaker,
"side": side,
"avatarKey": avatar_key,
}
used_participant_ids.add(participant["id"])
if config["avatarMode"] in {"upload", "mixed"} and configured.get("uploadPath"):
participant["uploadPath"] = configured["uploadPath"]
if config["avatarMode"] == "upload" and not participant.get("uploadPath"):
raise ValueError(f"avatarMode=upload requires uploadPath for participant {speaker}")
participants[speaker] = participant
participant = participants[speaker]
side = message["side"] or participant["side"]
if side != participant["side"]:
raise ValueError(f"Participant {speaker} appears on both {participant['side']} and {side}; use one side per participant")
avatar_key = participant["avatarKey"]
if message["avatar"] and message["avatar"] != participant["avatarKey"] and not configured_participant(speaker, config).get("preset"):
raise ValueError(f"Participant {speaker} has conflicting transcript avatar hints: {participant['avatarKey']} and {message['avatar']}; set a config preset to override")
messages.append(
{
"id": f"msg-{index + 1}",
"speaker": speaker,
"text": message["text"].strip(),
"side": side,
"avatarKey": avatar_key,
"appearAt": start + index * gap,
"highlight": bool(message["highlight"]),
}
)
if config["avatarMode"] == "mixed" and not any(participant.get("uploadPath") for participant in participants.values()):
raise ValueError("avatarMode=mixed requires at least one upload path")
duration = start + max(len(messages) - 1, 0) * gap + int(meta["hold"])
runtime_output = DELIVERY_TO_OUTPUT[config["deliveryFormat"]]
scene_config = {key: value for key, value in config.items() if key != "participants"}
return {
"title": meta["title"],View on GitHub (pinned to 5be4028344)
Solutions
- Set a single 'preset' under config.participants for that speaker; config preset wins and transcript hints are ignored.
- Make all transcript avatar hints for that speaker identical and a valid PRESET_KEYS value.
- Remove the avatar field from the conflicting transcript lines so the auto-assignment path is used.
Example fix
// before
// transcript:
Bob|left|female-fox-yellow|hi
Bob|left|male-bear-mint|yo
// config has no Bob preset -> after (config)
{"participants": {"Bob": {"side": "left", "preset": "female-fox-yellow"}}} Defensive patterns
Strategy: validation
Validate before calling
PRESET_KEYS = {"female-bunny-pink","female-cat-orange","female-fox-yellow","male-bear-mint","male-penguin-blue","male-koala-lilac"}
def check_avatar_hint_consistency(transcript_path, config):
configured = {n for n, p in config.get("participants", {}).items() if p.get("preset")}
hints = {}
for raw in transcript_path.read_text(encoding="utf-8").splitlines():
parts = [p.strip() for p in raw.split("|")] if "|" in raw else []
if len(parts) < 4:
continue
avatar, speaker = parts[-2], parts[0]
if avatar not in PRESET_KEYS or speaker in configured:
continue
if speaker in hints and hints[speaker] != avatar:
raise ValueError(f"{speaker} has conflicting avatar hints; set a config preset")
hints[speaker] = avatar Prevention
- Pin a single avatar per speaker via config 'preset' when in doubt.
- Remove inline avatar hints once a config preset is set.
When it happens
Trigger: Two transcript lines for the same speaker use different avatar tokens in the avatar slot (e.g. `Bob|left|female-fox-yellow|hi` and `Bob|left|male-bear-mint|yo`), and config.participants has no 'preset' for that speaker.
Common situations: Copy-pasting message lines from different templates; partially editing avatar hints; intending per-message avatar variety (which the spec does not support without a config preset).
Related errors
- Participant {speaker} appears on both {participant['side']}
- Unsupported avatar key for participant {speaker}: {avatar_ke
- avatarMode=preset does not allow uploadPath for participant
- avatarMode=upload requires uploadPath for participant {speak
- avatarMode=mixed requires at least one upload path
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/3318d75fbf95a948.
Report an issue: GitHub.