nexu-io/open-design · error · ValueError
Unsupported avatarMode: {config['avatarMode']}
Error message
Unsupported avatarMode: {config['avatarMode']} What it means
Raised by validate_config when config['avatarMode'] is not in ALLOWED_AVATAR_MODES = {"preset","upload","mixed"}. Default is 'preset'. 'preset' uses a built-in avatar key per participant; 'upload' requires each participant to supply uploadPath; 'mixed' allows per-participant choice.
Source
Thrown at skills/chat-motion-overlay/scripts/build_chat_overlay_spec.py:125
return value.strip().lower() == "highlight"
def load_config(path: str | None) -> dict:
config = json.loads(json.dumps(DEFAULT_CONFIG))
if not path:
validate_config(config)
return config
user = json.loads(Path(path).read_text(encoding="utf-8"))
config.update(user)
validate_config(config)
return config
def validate_config(config: dict) -> None:
if config["container"] not in ALLOWED_CONTAINERS:
raise ValueError(f"Unsupported container: {config['container']}")
if config["avatarMode"] not in ALLOWED_AVATAR_MODES:
raise ValueError(f"Unsupported avatarMode: {config['avatarMode']}")
if config["deviceFrame"] not in ALLOWED_DEVICE_FRAMES:
raise ValueError(f"Unsupported deviceFrame: {config['deviceFrame']}")
if config["nicknameMode"] not in ALLOWED_NICKNAME_MODES:
raise ValueError(f"Unsupported nicknameMode: {config['nicknameMode']}")
if config["deliveryFormat"] not in ALLOWED_DELIVERY_FORMATS:
raise ValueError(f"Unsupported deliveryFormat: {config['deliveryFormat']}")
if config["container"] == "none" and config["deviceFrame"] == "iphone-dynamic-island":
raise ValueError("container=none does not support deviceFrame=iphone-dynamic-island; use deviceFrame=none or choose an app container")
for speaker, participant in config.get("participants", {}).items():
side = participant.get("side")
if side and side not in {"left", "right"}:
raise ValueError(f"Unsupported side for participant {speaker}: {side}")
preset_key = participant.get("preset")
if preset_key and preset_key not in PRESET_KEYS:
raise ValueError(f"Unsupported preset for participant {speaker}: {preset_key}")
upload_path = participant.get("uploadPath")
if participant.get("uploadAsset"):View on GitHub (pinned to 5be4028344)
Solutions
- Set avatarMode to one of: preset, upload, mixed.
- For 'no avatars', choose 'preset' and rely on nicknameMode/container styling, or open a feature request — there is no 'off' mode.
- Pair the mode with required fields: upload requires uploadPath per participant; preset disallows uploadPath (see errors 578/579).
- Pre-validate: `assert c['avatarMode'] in {'preset','upload','mixed'}`.
Example fix
// before
{"avatarMode": "auto"}
# -> ValueError: Unsupported avatarMode: auto
// after
{"avatarMode": "upload", "participants": {"Alice": {"uploadPath": "/abs/avatar.png"}}} Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_AVATAR_MODES = {"preset", "upload", "mixed"}
if config["avatarMode"] not in ALLOWED_AVATAR_MODES:
raise SystemExit(
f"avatarMode must be one of {sorted(ALLOWED_AVATAR_MODES)}; "
f"got {config['avatarMode']!r}"
) Type guard
def is_avatar_mode(value) -> bool:
return value in {"preset", "upload", "mixed"} Try / catch
try:
validate_config(config)
except ValueError as exc:
raise SystemExit(f"Config error: {exc}") from exc Prevention
- Pair avatarMode with the required participant fields at validation time (upload needs uploadPath, preset forbids it).
- Document that there is no 'off' mode for avatars.
- Use jsonschema with an enum constraint to catch typos at config load.
- Prefer 'mixed' when participants vary.
When it happens
Trigger: User sets `"avatarMode": "auto"`, `"avatarMode": "none"`, `"avatarMode": "custom"`, or misspells 'preset'. Also triggered by JSON null or a numeric value.
Common situations: Guessing mode names; wanting 'no avatars' and trying 'none' (not supported — there is no off mode); stale config from an older build; case mismatch ('Preset').
Related errors
- Unsupported preset for participant {speaker}: {preset_key}
- Unsupported container: {config['container']}
- Unsupported deviceFrame: {config['deviceFrame']}
- Unsupported nicknameMode: {config['nicknameMode']}
- Unsupported deliveryFormat: {config['deliveryFormat']}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/30bd5fe31db42769.
Report an issue: GitHub.