nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError
mode action must be dark or light
Error message
mode action must be dark or light
What it means
Actions with the mode: prefix accept exactly two values: "dark" or "light" (membership test against {"dark", "light"}). Any other string — "dark-mode", "Dark", "auto", "system" — raises this ValueError, because apply_decision_rules stores the value directly as the result's mode field which downstream design-system generation switches on.
Source
Thrown at src/ui-ux-pro-max/scripts/reasoning_contract.py:98
for action in actions:
_validate_action(action)
if len(actions) != len(set(actions)):
raise ValueError("{} contains duplicate actions".format(condition))
return rules
def _validate_action(action):
if not isinstance(action, str) or ":" not in action:
raise ValueError("action must use a known prefix: {}".format(action))
prefix, value = action.split(":", 1)
if prefix not in ACTION_PREFIXES:
raise ValueError("unknown decision-rule action: {}".format(action))
if prefix in TOKEN_ACTION_PREFIXES and not TOKEN_RE.fullmatch(value):
raise ValueError("invalid {} action value: {}".format(prefix, value))
if prefix == "pattern" and not value.strip():
raise ValueError("pattern action must name a pattern")
if prefix == "mode" and value not in {"dark", "light"}:
raise ValueError("mode action must be dark or light")
def apply_decision_rules(rules, query):
"""Return deterministic mutations and an audit trail; never execute data."""
normalized = str(query or "").casefold()
result = {"activated": [], "style_ids": [], "constraints": [],
"pattern": None, "mode": None}
for condition, actions in rules.items():
active = condition == "must_have" or any(
pattern.search(normalized)
for pattern in CONDITION_PATTERNS.get(condition, ()))
if not active:
continue
result["activated"].append({"condition": condition, "actions": list(actions)})
for action in actions:
prefix, value = action.split(":", 1)
if prefix == "style" and value not in result["style_ids"]:
result["style_ids"].append(value)View on GitHub (pinned to a38d04c3d5)
Solutions
- Use exactly "mode:dark" or "mode:light" (lowercase).
- If conditional/auto theming is desired, encode it as separate if_ conditions (e.g. if_light_mode_needed already exists in the vocabulary) rather than a mode value.
- Case-normalize user input before composing rule JSON: value.lower().
Example fix
// before
{"if_mobile": ["mode:Dark", "mode:auto"]}
// after
{"if_mobile": ["mode:dark"]} Defensive patterns
Strategy: validation
Validate before calling
VALID_MODES = {"dark", "light"}
for a in all_actions:
prefix, _, value = a.partition(":")
if prefix == "mode" and value not in VALID_MODES:
raise ValueError(f"mode action must be dark or light; got {value!r}") Type guard
def is_valid_mode_value(value: str) -> bool:
return value in {"dark", "light"} Prevention
- Normalize mode input with value.strip().lower() before composing the action string.
- Encode conditional theming via if_ conditions (e.g. if_light_mode_needed), never via mode values like 'auto'.
When it happens
Trigger: _validate_action("mode:Dark") (case-sensitive), _validate_action("mode:auto"), _validate_action("mode:dark-mode") — inside any condition's action array passed to parse_decision_rules.
Common situations: Rules written from memory with common theme-toggle vocabulary ("auto", "system"); capitalization copied from prose docs.
Related errors
- duplicate decision-rule key: {}
- decision rules must be a JSON object
- unknown decision-rule condition: {}
- {} must map to a non-empty action array
- {} contains duplicate actions
AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14).
Data as JSON: /api/errors/76f3dacb12f3b9a2.
Report an issue: GitHub.