RFC 8259 says names SHOULD be unique, and otherwise "the behavior of software that receives such an object is unpredictable". A repeated key is still valid JSON:
DOC='{"book_id": 1, "qty": 1, "qty": 50}'
echo "$DOC" | python3 -c 'import json, sys; print(json.load(sys.stdin))'
echo "$DOC" | jq -c .
duckdb -noheader -list -c "SELECT j->>'qty', json_keys(j) FROM (SELECT '$DOC'::JSON AS j)"{'book_id': 1, 'qty': 50}
{"book_id":1,"qty":50}
1|[book_id, qty, qty]Python and jq 133,477 keep the last value; DuckDB 61,228 keeps both and ->> returns the first. Attackers exploit such parser differentials: a gateway checks the first "role", the backend obeys the second. Reject duplicates at ingestion, for example with a Python object_pairs_hook that raises on a repeat. Order is equally unreliable: PostgreSQL 18 1,289 's json keeps the text verbatim, while jsonb turned the same line into {"qty": 50, "book_id": 1}. Never hash or compare JSON as text; canonicalize it first (RFC 8785) or compare parsed values, and sort keys with jq -S before a diff.