nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError
unknown decision-rule action: {}
Error message
unknown decision-rule action: {} What it means
After splitting an action at its first ':', the prefix must be one of ACTION_PREFIXES = {constraint, style, pattern, mode} (reasoning_contract.py:46). Any other prefix — a typo like 'themes:', an invented verb like 'enable:', or a renamed prefix from a different toolkit version — raises this ValueError echoing the full action.
Source
Thrown at src/ui-ux-pro-max/scripts/reasoning_contract.py:92
raise ValueError("decision rules must be a JSON object")
for condition, actions in rules.items():
if condition not in ALLOWED_CONDITIONS:
raise ValueError("unknown decision-rule condition: {}".format(condition))
if not isinstance(actions, list) or not actions:
raise ValueError("{} must map to a non-empty action array".format(condition))
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:View on GitHub (pinned to a38d04c3d5)
Solutions
- Use only the four prefixes: constraint:, style:, pattern:, mode:.
- If you intended a new effect kind, add it to ACTION_PREFIXES (and TOKEN_ACTION_PREFIXES if its value is a kebab-token) in reasoning_contract.py, plus handling in apply_decision_rules and tests.
- Check for stale rule payloads after upgrading the toolkit if the prefix set changed.
Example fix
// before
{"if_luxury": ["themes:gold"]}
// after
{"if_luxury": ["style:luxury-gold"]} Defensive patterns
Strategy: validation
Validate before calling
from src.ui_ux_pro_max.scripts.reasoning_contract import ACTION_PREFIXES
bad = [a for a in all_actions if a.split(":", 1)[0] not in ACTION_PREFIXES]
if bad:
raise ValueError(f"actions with unknown prefix: {bad}; allowed prefixes: {sorted(ACTION_PREFIXES)}") Type guard
def has_known_prefix(action: str) -> bool:
return action.split(":", 1)[0] in {"constraint", "style", "pattern", "mode"} Prevention
- Derive allowed prefixes from ACTION_PREFIXES rather than a local copy, so vocabulary changes propagate.
- Add contract unit tests whenever you extend ACTION_PREFIXES.
When it happens
Trigger: _validate_action("themes:dark"), _validate_action("font:serif"), or _validate_action("enable:pattern") — all pass the ':' check at line 90 but fail the prefix membership test at line 92.
Common situations: Extending the rule vocabulary without updating ACTION_PREFIXES; porting rules from another design-system tool with different action names.
Related errors
- unknown decision-rule condition: {}
- duplicate decision-rule key: {}
- decision rules must be a JSON object
- {} 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/4657c1a54b6e09f2.
Report an issue: GitHub.