affaan-m/ECC · error · ValueError

duplicate JSON field

Error message

duplicate JSON field

What it means

The library parses JSON with a custom object_pairs_hook that rejects any object containing the same key twice, raising "duplicate JSON field". Standard json.loads silently keeps only the last duplicate, which would make hash-bound bundles ambiguous, so duplicates are treated as invalid input.

Solutions

  1. Open the file and find the duplicated key in the offending object (JSON parsers don't report its location — try a strict parser like `python -c "import json,sys; json.load(open(sys.argv[1]), object_pairs_hook=lambda p: [p])"` style checks or jq with duplicate detection) and delete one occurrence.
  2. Regenerate the file from its source tool instead of hand-merging.
  3. Run a pre-check with a strict parser that flags duplicates before handing the path to the library.

Example fix

// before
{"timeline_name": "main", "timeline_name": "main_v2"}

// after
{"timeline_name": "main_v2"}
Defensive patterns

Strategy: validation

Validate before calling

import json, sys
def reject_duplicate_keys(path):
    def hook(pairs):
        keys = [k for k, _ in pairs]
        if len(keys) != len(set(keys)):
            raise ValueError(f"{path}: duplicate JSON field {set(k for k in keys if keys.count(k) > 1)}")
        return dict(pairs)
    with open(path, encoding="utf-8") as f:
        json.load(f, object_pairs_hook=hook)

Try / catch

try:
    request = load_application_request(path)
except ValueError as exc:
    if "duplicate JSON field" in str(exc):
        print(f"{path}: merge edits carefully; remove repeated keys")
    raise

Prevention

When it happens

Trigger: Any JSON artifact parsed by this module (request file, snapshot, receipt, approval file) contains an object literal with the same key appearing two or more times, e.g. {"fps": {"numerator": 24000, "numerator": 24000, ...}}.

Common situations: Hand-merged config files where two edits both added the same key; template concatenation; a generator bug emitting a key twice; copy-pasted JSON blocks.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/64270df022f21577. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/integration.py:175

            os.close(descriptor)
        if parent is not None:
            os.close(parent)


def load_application_request(path: str | Path) -> dict:
    """Load only a bounded resident request; never follow a config symlink."""
    value = _read_local(str(Path(path).absolute()), parse_json=True)
    if not isinstance(value, dict):
        raise ValueError("application request must be a JSON object")
    return value


def _load_json(data: bytes) -> Any:
    def unique(pairs):
        result = {}
        for key, value in pairs:
            if key in result:
                raise ValueError("duplicate JSON field")
            result[key] = value
        return result

    try:
        value = json.loads(data, object_pairs_hook=unique)
        _canonical(value)
        return value
    except (UnicodeError, RecursionError) as exc:
        raise ValueError("invalid JSON artifact") from exc


def _snapshot(baseline: dict) -> dict:
    _object(baseline, {"project_file", "snapshot_file", "project_name", "timeline_name",
                       "fps", "timeline_range"})
    _rate(baseline["fps"])
    bounds = _range(baseline["timeline_range"])
    _artifact(baseline["project_file"])
    snapshot = _artifact(baseline["snapshot_file"], parse_json=True)

View on GitHub (pinned to 8321021c54)