{"record":{"id":"bc3c09bbd4db0eb7","repo":"nextlevelbuilder/ui-ux-pro-max-skill","slug":"duplicate-decision-rule-key","errorCode":null,"errorMessage":"duplicate decision-rule key: {}","messagePattern":"duplicate decision-rule key: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/ui-ux-pro-max/scripts/reasoning_contract.py","lineNumber":62,"sourceCode":"\nALLOWED_CONDITIONS = {\"must_have\", *CONDITION_SIGNALS}\nACTION_PREFIXES = {\"constraint\", \"style\", \"pattern\", \"mode\"}\nTOKEN_ACTION_PREFIXES = {\"constraint\", \"style\"}\nTOKEN_RE = re.compile(r\"^[a-z0-9]+(?:-[a-z0-9]+)*$\")\nCONDITION_PATTERNS = {\n    condition: tuple(\n        re.compile(r\"(?<!\\w)\" + re.escape(signal) + r\"(?!\\w)\")\n        for signal in signals\n    )\n    for condition, signals in CONDITION_SIGNALS.items()\n}\n\n\ndef _object_without_duplicates(pairs):\n    result = {}\n    for key, value in pairs:\n        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:","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill/blob/a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5/src/ui-ux-pro-max/scripts/reasoning_contract.py#L44-L80","documentation":"reasoning_contract.py parses decision-rule JSON with object_pairs_hook=_object_without_duplicates, which rejects duplicate keys inside any JSON object. Python's default json.loads silently keeps the last duplicate; this hook instead raises so a rule file can never rely on accidental overwrite semantics. Duplicate condition keys (e.g. two \"must_have\" entries) are the typical trigger.","triggerScenarios":"Calling parse_decision_rules(raw) where raw is a JSON string containing the same object key twice at any level — commonly two `\"if_mobile\": [...]` entries produced by merging rule files or by a bad copy-paste in the decisionRules column of a CSV/design-system payload.","commonSituations":"Hand-editing a decisionRules JSON blob in a spreadsheet cell and duplicating a condition; programmatic concatenation of two rule objects via string join instead of dict merge.","solutions":["Locate the duplicated key named in the message within the decision-rule JSON string and delete one occurrence.","If merging two rule sets, merge Python dicts before serializing (`{**a, **b}`) rather than concatenating JSON text.","Validate with `python3 -c \"import json;json.loads(open(f).read(), object_pairs_hook=lambda p: p)\"` style tooling, or just call parse_decision_rules on the candidate payload before saving."],"exampleFix":"// before\n{\"must_have\":[\"mode:dark\"],\"must_have\":[\"style:neo-brutalism\"]}\n\n// after\n{\"must_have\":[\"mode:dark\",\"style:neo-brutalism\"]}","handlingStrategy":"validation","validationCode":"import json\ndef has_duplicate_keys(raw):\n    seen = []\n    def hook(pairs):\n        keys = [k for k, _ in pairs]\n        if len(keys) != len(set(keys)):\n            seen.extend(k for k in keys if keys.count(k) > 1)\n        return dict(pairs)\n    json.loads(raw or \"{}\", object_pairs_hook=hook)\n    return sorted(set(seen))\n\ndups = has_duplicate_keys(rule_json)\nif dups:\n    raise ValueError(f\"fix duplicate keys before parse_decision_rules: {dups}\")","typeGuard":null,"tryCatchPattern":"from src.ui_ux_pro_max.scripts import reasoning_contract as rc\ntry:\n    rules = rc.parse_decision_rules(raw)\nexcept ValueError as exc:\n    # all contract errors (syntax, duplicates, vocabulary) arrive as ValueError\n    log_and_reject_payload(raw, str(exc))","preventionTips":["Merge rule dicts programmatically, never by concatenating JSON strings.","Run parse_decision_rules as a pre-save lint on every edited rule payload.","Keep rule authoring in structured editors that flag duplicate JSON keys."],"tags":["json","duplicate-keys","decision-rules","validation"],"backgroundTag":null,"analyzedSha":"a38d04c3d5c298c851dbe5e6ee1965ee3de42cb5","analyzedAt":"2026-08-14T18:51:02.321Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}