nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError

invalid {} action value: {}

Error message

invalid {} action value: {}

What it means

For token-valued prefixes (TOKEN_ACTION_PREFIXES = {constraint, style}, reasoning_contract.py:47), the value after the colon must fully match TOKEN_RE = ^[a-z0-9]+(?:-[a-z0-9]+)*$ — lowercase kebab-case tokens only. Uppercase letters, underscores, spaces, leading/trailing hyphens, or slashes fail. The pattern: and mode: values are exempt (they have their own checks) which is why the message interpolates the specific prefix.

Source

Thrown at src/ui-ux-pro-max/scripts/reasoning_contract.py:94

        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:
            continue
        result["activated"].append({"condition": condition, "actions": list(actions)})

View on GitHub (pinned to a38d04c3d5)

Solutions

  1. Normalize the value to lowercase kebab-case: "style:neo-brutalism", "constraint:no-large-images".
  2. Strip stray whitespace and leading/trailing hyphens before saving.
  3. Cross-check style tokens against the actual style IDs in src/ui-ux-pro-max/data/styles.csv so the value also resolves at apply time.

Example fix

// before
{"must_have": ["style:Neo_Brutalism", "constraint: no_large_images"]}

// after
{"must_have": ["style:neo-brutalism", "constraint:no-large-images"]}
Defensive patterns

Strategy: validation

Validate before calling

import re
from src.ui_ux_pro_max.scripts.reasoning_contract import TOKEN_RE, TOKEN_ACTION_PREFIXES
for a in all_actions:
    prefix, _, value = a.partition(":")
    if prefix in TOKEN_ACTION_PREFIXES and not TOKEN_RE.fullmatch(value):
        raise ValueError(f"{a}: value must be lowercase kebab-case [a-z0-9-]; got {value!r}")

Type guard

def is_kebab_token(value: str) -> bool:
    return bool(re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", value))

Prevention

When it happens

Trigger: _validate_action("style:Neo_Brutalism"), "constraint: no-large-images" (space), "constraint:ui/ux" (slash), or "style:-minimal" (leading hyphen) — reached when parse_decision_rules iterates actions of any condition.

Common situations: Copying style IDs or constraint slugs from documentation that uses Title_Case or underscores; CSV cells preserving leading whitespace after a delimiter.

Related errors


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