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

  1. Use only the four prefixes: constraint:, style:, pattern:, mode:.
  2. 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.
  3. 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

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


AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14). Data as JSON: /api/errors/4657c1a54b6e09f2. Report an issue: GitHub.