{"record":{"id":"64270df022f21577","repo":"affaan-m/ECC","slug":"duplicate-json-field","errorCode":null,"errorMessage":"duplicate JSON field","messagePattern":"duplicate JSON field","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":175,"sourceCode":"            os.close(descriptor)\n        if parent is not None:\n            os.close(parent)\n\n\ndef load_application_request(path: str | Path) -> dict:\n    \"\"\"Load only a bounded resident request; never follow a config symlink.\"\"\"\n    value = _read_local(str(Path(path).absolute()), parse_json=True)\n    if not isinstance(value, dict):\n        raise ValueError(\"application request must be a JSON object\")\n    return value\n\n\ndef _load_json(data: bytes) -> Any:\n    def unique(pairs):\n        result = {}\n        for key, value in pairs:\n            if key in result:\n                raise ValueError(\"duplicate JSON field\")\n            result[key] = value\n        return result\n\n    try:\n        value = json.loads(data, object_pairs_hook=unique)\n        _canonical(value)\n        return value\n    except (UnicodeError, RecursionError) as exc:\n        raise ValueError(\"invalid JSON artifact\") from exc\n\n\ndef _snapshot(baseline: dict) -> dict:\n    _object(baseline, {\"project_file\", \"snapshot_file\", \"project_name\", \"timeline_name\",\n                       \"fps\", \"timeline_range\"})\n    _rate(baseline[\"fps\"])\n    bounds = _range(baseline[\"timeline_range\"])\n    _artifact(baseline[\"project_file\"])\n    snapshot = _artifact(baseline[\"snapshot_file\"], parse_json=True)","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L157-L193","documentation":"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.","triggerScenarios":"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, ...}}.","commonSituations":"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.","solutions":["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.","Regenerate the file from its source tool instead of hand-merging.","Run a pre-check with a strict parser that flags duplicates before handing the path to the library."],"exampleFix":"// before\n{\"timeline_name\": \"main\", \"timeline_name\": \"main_v2\"}\n\n// after\n{\"timeline_name\": \"main_v2\"}","handlingStrategy":"validation","validationCode":"import json, sys\ndef reject_duplicate_keys(path):\n    def hook(pairs):\n        keys = [k for k, _ in pairs]\n        if len(keys) != len(set(keys)):\n            raise ValueError(f\"{path}: duplicate JSON field {set(k for k in keys if keys.count(k) > 1)}\")\n        return dict(pairs)\n    with open(path, encoding=\"utf-8\") as f:\n        json.load(f, object_pairs_hook=hook)","typeGuard":null,"tryCatchPattern":"try:\n    request = load_application_request(path)\nexcept ValueError as exc:\n    if \"duplicate JSON field\" in str(exc):\n        print(f\"{path}: merge edits carefully; remove repeated keys\")\n    raise","preventionTips":["Never hand-merge JSON config blocks; use a merging tool that dedupes.","Run a duplicate-key linter (e.g. json.tool with a strict hook) in CI.","Generate configs from a single source of truth.","Avoid copy-pasting JSON fragments between files."],"tags":["json","duplicate-keys","validation"],"backgroundTag":"json-parse-error","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}