nextlevelbuilder/ui-ux-pro-max-skill · error · ValueError
invalid decision-rule JSON: {}
Error message
invalid decision-rule JSON: {} What it means
parse_decision_rules wraps json.loads and converts any json.JSONDecodeError into this ValueError with the underlying parse error appended. The decision-rule grammar only accepts well-formed JSON objects, so trailing commas, single quotes, comments, or truncation fail here before semantic validation begins.
Source
Thrown at src/ui-ux-pro-max/scripts/reasoning_contract.py:72
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:
_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)View on GitHub (pinned to a38d04c3d5)
Solutions
- Copy the JSON string into a linter or `python3 -m json.tool` to find the exact syntax offset reported in the message.
- Quote all keys and string values with double quotes; remove trailing commas and comments.
- If the payload comes from a CSV column, check the cell was not truncated or line-wrapped on import.
Example fix
// before
{'if_mobile': ['mode:dark'],} // single quotes + trailing comma
// after
{"if_mobile": ["mode:dark"]} Defensive patterns
Strategy: validation
Validate before calling
import json
try:
candidate = json.loads(raw)
except json.JSONDecodeError as exc:
raise ValueError(f"payload is not valid JSON at line {exc.lineno} col {exc.colno}: {exc.msg}") from exc
# only then hand to parse_decision_rules for contract checks Try / catch
try:
rules = rc.parse_decision_rules(raw)
except ValueError as exc:
if 'invalid decision-rule JSON' in str(exc):
show_json_syntax_error(raw, str(exc)) # message embeds json's own position info
raise Prevention
- Author rule JSON with json.dumps from Python data, never by string building.
- Pipe hand-written payloads through `python3 -m json.tool` before saving.
- Watch CSV-hosted JSON for truncation on import (quote fields, raise cell length limits).
When it happens
Trigger: parse_decision_rules(raw) with raw like `{if_mobile: [...]}` (unquoted key), `{"a": [1,],}` (trailing comma), a string truncated by a CSV field limit, or None passed through as '{}' only when raw is falsy — a non-empty malformed string still hits json.loads.
Common situations: Writing rule JSON inline in a CSV cell and forgetting quotes around condition keys; shell heredocs mangling quotes; spreadsheet export truncating long cells.
Related errors
- duplicate decision-rule key: {}
- decision rules must be a JSON object
- {} must map to a non-empty action array
- {} contains duplicate actions
- Unterminated quoted CSV field
AI-assisted analysis of nextlevelbuilder/ui-ux-pro-max-skill@a38d04c3d5 (2026-08-14).
Data as JSON: /api/errors/bfd599964ce693c9.
Report an issue: GitHub.