{"record":{"id":"bc66763b87201d7a","repo":"nextlevelbuilder/ui-ux-pro-max-skill","slug":"must-map-to-a-non-empty-action-array","errorCode":null,"errorMessage":"{} must map to a non-empty action array","messagePattern":"(.+?) must map to a non-empty action array","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/ui-ux-pro-max/scripts/reasoning_contract.py","lineNumber":79,"sourceCode":"        if key in result:\n            raise ValueError(\"duplicate decision-rule key: {}\".format(key))\n        result[key] = value\n    return result\n\n\ndef parse_decision_rules(raw):\n    \"\"\"Parse the canonical condition -> action-array representation.\"\"\"\n    try:\n        rules = json.loads(raw or \"{}\", object_pairs_hook=_object_without_duplicates)\n    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\"}:","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill/blob/a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5/src/ui-ux-pro-max/scripts/reasoning_contract.py#L61-L97","documentation":"Every condition key in the decision-rule object must map to a non-empty JSON array of action strings. Mapping to a scalar, an object, an empty array [], or null raises this ValueError naming the condition. Empty arrays are rejected because a condition that activates but does nothing is indistinguishable from a mistake.","triggerScenarios":"parse_decision_rules('{\"if_mobile\": \"mode:dark\"}') (string not array), '{\"must_have\": []}' (empty), '{\"if_luxury\": {\"style\":\"luxury-gold\"}}' (object), or '{\"if_booking\": null}'.","commonSituations":"Compressing a single action to a scalar for brevity; clearing a rule by emptying its array instead of deleting the key; a schema drift where actions were once objects.","solutions":["Wrap actions in an array: \"mode:dark\" becomes [\"mode:dark\"].","Delete the condition key entirely if it should have no actions.","Ensure each element is an action string — the array shape is validated further by _validate_action."],"exampleFix":"// before\n{\"if_mobile\": \"mode:dark\", \"if_luxury\": []}\n\n// after\n{\"if_mobile\": [\"mode:dark\"]}","handlingStrategy":"validation","validationCode":"import json\nrules = json.loads(raw)\nfor cond, actions in rules.items():\n    if not isinstance(actions, list) or not actions:\n        raise ValueError(f\"{cond} must map to a non-empty list; got {actions!r}\")","typeGuard":"def is_non_empty_action_list(value) -> bool:\n    return isinstance(value, list) and len(value) > 0 and all(isinstance(a, str) for a in value)","tryCatchPattern":null,"preventionTips":["Delete condition keys that no longer apply instead of emptying their arrays.","Keep single actions wrapped in brackets in templates and examples so the array shape is never 'simplified'."],"tags":["decision-rules","validation","schema","json"],"backgroundTag":null,"analyzedSha":"a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5","analyzedAt":"2026-08-14T18:51:02.321Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}