nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError
duplicate decision-rule key: {}
Error message
duplicate decision-rule key: {} What it means
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.
Source
Thrown at src/ui-ux-pro-max/scripts/reasoning_contract.py:62
ALLOWED_CONDITIONS = {"must_have", *CONDITION_SIGNALS}
ACTION_PREFIXES = {"constraint", "style", "pattern", "mode"}
TOKEN_ACTION_PREFIXES = {"constraint", "style"}
TOKEN_RE = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
CONDITION_PATTERNS = {
condition: tuple(
re.compile(r"(?<!\w)" + re.escape(signal) + r"(?!\w)")
for signal in signals
)
for condition, signals in CONDITION_SIGNALS.items()
}
def _object_without_duplicates(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError("duplicate decision-rule key: {}".format(key))
result[key] = value
return result
def parse_decision_rules(raw):
"""Parse the canonical condition -> action-array representation."""
try:
rules = json.loads(raw or "{}", object_pairs_hook=_object_without_duplicates)
except json.JSONDecodeError as error:
raise ValueError("invalid decision-rule JSON: {}".format(error)) from error
if not isinstance(rules, dict):
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:View on GitHub (pinned to a38d04c3d5)
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.
Example fix
// before
{"must_have":["mode:dark"],"must_have":["style:neo-brutalism"]}
// after
{"must_have":["mode:dark","style:neo-brutalism"]} Defensive patterns
Strategy: validation
Validate before calling
import json
def has_duplicate_keys(raw):
seen = []
def hook(pairs):
keys = [k for k, _ in pairs]
if len(keys) != len(set(keys)):
seen.extend(k for k in keys if keys.count(k) > 1)
return dict(pairs)
json.loads(raw or "{}", object_pairs_hook=hook)
return sorted(set(seen))
dups = has_duplicate_keys(rule_json)
if dups:
raise ValueError(f"fix duplicate keys before parse_decision_rules: {dups}") Try / catch
from src.ui_ux_pro_max.scripts import reasoning_contract as rc
try:
rules = rc.parse_decision_rules(raw)
except ValueError as exc:
# all contract errors (syntax, duplicates, vocabulary) arrive as ValueError
log_and_reject_payload(raw, str(exc)) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- decision rules must be a JSON object
- {} must map to a non-empty action array
- {} contains duplicate actions
- Invalid JSON file {path}: {error}
- invalid decision-rule JSON: {}
AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14).
Data as JSON: /api/errors/bc3c09bbd4db0eb7.
Report an issue: GitHub.