{"record":{"id":"a0a55de63320e217","repo":"nextlevelbuilder/ui-ux-pro-max-skill","slug":"action-must-use-a-known-prefix","errorCode":null,"errorMessage":"action must use a known prefix: {}","messagePattern":"action must use a known prefix: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/ui-ux-pro-max/scripts/reasoning_contract.py","lineNumber":89,"sourceCode":"    except json.JSONDecodeError as error:\n        raise ValueError(\"invalid decision-rule JSON: {}\".format(error)) from error\n    if not isinstance(rules, dict):\n        raise ValueError(\"decision rules must be a JSON object\")\n    for condition, actions in rules.items():\n        if condition not in ALLOWED_CONDITIONS:\n            raise ValueError(\"unknown decision-rule condition: {}\".format(condition))\n        if not isinstance(actions, list) or not actions:\n            raise ValueError(\"{} must map to a non-empty action array\".format(condition))\n        for action in actions:\n            _validate_action(action)\n        if len(actions) != len(set(actions)):\n            raise ValueError(\"{} contains duplicate actions\".format(condition))\n    return rules\n\n\ndef _validate_action(action):\n    if not isinstance(action, str) or \":\" not in action:\n        raise ValueError(\"action must use a known prefix: {}\".format(action))\n    prefix, value = action.split(\":\", 1)\n    if prefix not in ACTION_PREFIXES:\n        raise ValueError(\"unknown decision-rule action: {}\".format(action))\n    if prefix in TOKEN_ACTION_PREFIXES and not TOKEN_RE.fullmatch(value):\n        raise ValueError(\"invalid {} action value: {}\".format(prefix, value))\n    if prefix == \"pattern\" and not value.strip():\n        raise ValueError(\"pattern action must name a pattern\")\n    if prefix == \"mode\" and value not in {\"dark\", \"light\"}:\n        raise ValueError(\"mode action must be dark or light\")\n\n\ndef apply_decision_rules(rules, query):\n    \"\"\"Return deterministic mutations and an audit trail; never execute data.\"\"\"\n    normalized = str(query or \"\").casefold()\n    result = {\"activated\": [], \"style_ids\": [], \"constraints\": [],\n              \"pattern\": None, \"mode\": None}\n    for condition, actions in rules.items():\n        active = condition == \"must_have\" or any(","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill/blob/a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5/src/ui-ux-pro-max/scripts/reasoning_contract.py#L71-L107","documentation":"First check in _validate_action: every action must be a string containing a ':' separator, because actions are parsed as prefix:value (prefix in {constraint, style, pattern, mode}). Non-strings, strings without a colon, or empty values like \"mode:\" pattern-split failures all raise here with the offending action echoed.","triggerScenarios":"_validate_action receives 42 (int), None, \"mode dark\" (space instead of colon), \"dark\" (missing prefix), or \"\" — reached via parse_decision_rules validating every element of each condition's action array.","commonSituations":"Mixing action dialects (some systems use space-separated tokens); YAML/JSON autotyping turning a quoted action into a number; forgetting the prefix when authoring rules.","solutions":["Write every action as prefix:value, e.g. \"mode:dark\", \"style:minimal\", \"pattern:hero-split\", \"constraint:no-large-images\".","Quote all actions in the JSON payload so they stay strings.","Replace separators: 'mode dark' -> 'mode:dark'."],"exampleFix":"// before\n{\"must_have\": [\"dark\", 42]}\n\n// after\n{\"must_have\": [\"mode:dark\"]}","handlingStrategy":"validation","validationCode":"from src.ui_ux_pro_max.scripts.reasoning_contract import ACTION_PREFIXES\nimport json\nfor cond, actions in json.loads(raw).items():\n    for a in actions:\n        if not isinstance(a, str) or ':' not in a or a.split(':', 1)[0] not in ACTION_PREFIXES:\n            raise ValueError(f\"{cond}: malformed action {a!r}; use prefix:value with prefix in {sorted(ACTION_PREFIXES)}\")","typeGuard":"def is_wellformed_action(a) -> bool:\n    return isinstance(a, str) and \":\" in a and a.split(\":\", 1)[0] in {\"constraint\", \"style\", \"pattern\", \"mode\"}","tryCatchPattern":null,"preventionTips":["Provide a snippet library of the four valid action shapes for rule authors.","Validate actions at authoring time (spreadsheet macro or lint script), not only at parse time."],"tags":["decision-rules","action-syntax","validation"],"backgroundTag":null,"analyzedSha":"a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5","analyzedAt":"2026-08-14T18:51:02.321Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}