Guide

Duplicate keys in JSON: what happens and how to avoid them

Learn why repeated object names produce unpredictable results and how to catch data loss before converting JSON.

by Tools in a Tab · Published on · Updated

Short answer

A duplicate key in a JSON object has no portable outcome. The specification recommends unique names, but parsers may keep the first value, keep the last, preserve every occurrence, or reject the input. The safe response is to detect the repetition and decide what the data should mean before parsing or converting it.

A minimal example

This text follows the JSON grammar but repeats status:

{
  "status": "pending",
  "status": "shipped"
}

JavaScript’s JSON.parse keeps the last value, "shipped", for this example. That does not make the document unambiguous: another receiver can behave differently. Once the first value is discarded, formatting the parsed result cannot recover it.

Section 4 of RFC 8259 says object names should be unique and warns that behavior with repeated names is unpredictable across implementations.

How to fix it

First decide whether the repetition is accidental or represents several real values:

  • If only one status is current, keep one property.
  • If both values form a list, use an array with a descriptive name.
  • If they are historical events, model objects with an order or date rather than repeating a key.

For example, a sequence can be represented unambiguously:

{
  "history": [
    { "status": "pending", "order": 1 },
    { "status": "shipped", "order": 2 }
  ]
}

Check before losing the evidence

Detect duplicates in the original text, before turning it into a language object. Tools in a Tab’s JSON to CSV converter rejects duplicate names before producing rows because a table cannot decide which value belongs to the column.

The JSON validator keeps syntax and duplicate checks separate. With Also check duplicate keys enabled, it flags this example as valid syntax with an interoperability warning and locates both occurrences in the original text. Go to repetition selects the repeated name without changing the input. The JSON formatter preserves both occurrences because it formats the original tokens, not a parsed JavaScript object. Neither tool chooses the intended value or removes a property for you.

Therefore, “it parses” does not mean “it is interoperable.” Check names before a transformation that reduces them to one value; after that, the original collision may have disappeared.

Try a reproducible duplicate-key check

  1. Open the validator and press Load duplicate-key example, or download the exact JSON file and paste its text without first parsing and reserializing it.
  2. Keep Also check duplicate keys enabled and validate.
  3. Expect two repeated occurrences: status at line 4, column 3, and code at line 6, column 20. Their first occurrences are at line 3, column 3, and line 6, column 7, respectively.
  4. Follow Go to repetition and decide which data model you intended before editing anything.

The escaped spelling "sta\u0074us" is the same name as "status". Two separate objects may both have a code property without conflict; the warning belongs only to the object that repeats it. The same file contains 9007199254740993, which stays unchanged in the input. Native JavaScript numeric conversion can round it, so do not use a parse-and-reserialize step to prepare the test.

The check counts repeated occurrences rather than distinct names and displays the first 20. Inputs over 1,000,000 UTF-16 code units or nesting beyond 100 containers produce an explicit incomplete/not-checked notice, not a clean bill of health. Syntax errors must be fixed before this separate check runs.

Practical rule

Require unique names within each object, run a duplicate-name check at the boundary, and do not use ordering to resolve conflicts. If several values are needed, express them explicitly with an array or separate properties. The JSON will then preserve its meaning across languages, APIs, and tools.