What the validator actually does
The tool first calls `JSON.parse`. Invalid JSON stops there and reports an error, with a location when the parser provides one; a duplicate-key report is meaningful only after the document is syntactically valid. It then calculates a structural summary and, while the “Report duplicate keys” option remains on, scans the raw input for repeated quoted names in each object scope.
The option is on by default. When matches are found, the result lists up to twenty `line N: "key" (in the same object)` entries and adds a warning with the total. The output is not a rewritten JSON document, so it does not pretend to preserve both values. It is an instruction to repair the source before any parse-and-serialize step decides which value wins.
Turn the option off only when you need the structural summary and have already checked the source another way. Disabling it does not make duplicates safe; it merely omits this scanner. Formatting, minifying, JSON-to-CSV conversion and any other tool based on `JSON.parse` still see only the final parsed property.
{
"theme": "light",
"theme": "dark"
}Why the last value wins in this tool
JavaScript object properties have one value per name. During `JSON.parse`, a later member with the same name assigns that property again, replacing the earlier one. That makes the following input appear harmless after parsing: the output contains `timeout: 30`, but no normal object walk can prove that `timeout: 10` was present in the source first.
The order matters. In a generated document, a harmless default followed by a malicious or mistaken override can be treated differently by a different parser, proxy, validator or application. That disagreement is the real operational problem. “Last wins” describes this JavaScript implementation, not a portable guarantee you should rely on across systems.
Repair the producer rather than keeping a convention about which occurrence is authoritative. A review comment such as “keep the second one” leaves the next edit free to reverse their order. One name, one definition, and a test for the intended parsed value are substantially clearer.
| Source member order | This tool after JSON.parse | Safe action |
|---|---|---|
| `"timeout": 10`, then `"timeout": 30` | `timeout` is 30 | Keep one deliberate value |
| `"role": "user"`, then `"role": "admin"` | `role` is admin | Reject and fix the producer |
| Same name in separate nested objects | Both properties remain | Usually valid; their scopes differ |
Scope matters: nested names are not duplicates
A duplicate is two occurrences in the same object. Reusing a common name such as `id`, `name` or `enabled` in different objects is ordinary JSON and should not be renamed merely to satisfy a global search. The scanner tracks object braces as scopes so a top-level `id` and a nested `user.id` are treated independently.
Arrays do not create property names themselves, but objects inside arrays each have their own scope. Two array records can both contain `id`; that is the normal table-like shape. A repeated `id` inside one of those record objects is the case to fix. Read the reported line alongside the surrounding braces before changing anything.
This distinction is especially important with copied configuration blocks. A copied object can legitimately contain the same keys as its sibling. A merge that accidentally places both blocks’ contents into one object creates duplicates. The source may look nearly identical, while the braces decide whether the document has two records or one ambiguous record.
{
"id": "request-1",
"user": { "id": "user-9" },
"items": [{ "id": 1 }, { "id": 2 }]
}Know the raw-scanner limitations
The duplicate report scans text because parsing has already erased earlier values. Its scanner is simpler than a full JSON tokenizer: it skips a backslash and the following character rather than decoding that escape. Consequently, different spellings that decode to the same property name can evade the report, and names that are actually different can be reported as duplicates.
For example, `"a"` and `"\u0061"` decode to the same JavaScript property name, but the scanner compares `a` with `0061` and misses the duplicate. Conversely, `"ab"` and `"a\nb"` compare as `ab` in the scanner even though the second decoded key contains a newline. Do not remove one solely because of that warning: inspect the actual decoded names. A clean report is useful evidence for ordinary names, not a proof of uniqueness for hostile or heavily escaped input.
The scanner also reports at most twenty individual lines while retaining the total in its warning. For a generated document with many matches, fix the template or generator and run it again; do not treat the first twenty as the whole defect list. If uniqueness is a security boundary, use a parser or validation layer designed to reject duplicate decoded keys before application parsing.
{
"a": 1,
"\u0061": 2
}A review sequence that preserves evidence
Start with the original file, not a formatted copy. Run the JSON Validator with duplicate reporting enabled and save the source somewhere reviewable if the data matters. Read any duplicate lines in context, decide the intended value with the data owner, then delete or rename the unintended member in the producer.
Run the validator again. A valid result with no duplicate report is not a safety guarantee: review escaped names and precision-sensitive numbers before formatting. The JSON Formatter still parses and serializes, so it is excellent for a readable diff after the source problem is removed, but it cannot recover an earlier member that was discarded beforehand.
Finally, test the consumer’s expectation. Syntax validation cannot tell you whether `timeout` belongs at the top level, whether a URL is allowed, or whether a role is permitted. A JSON Schema or application-level test covers those semantic rules; duplicate-key detection protects the narrower but important rule that there is one unambiguous spelling of each property in an object.
- Validate the untouched source with “Report duplicate keys” enabled.
- Inspect each reported line in its object scope.
- Fix the template, merge step or editor action that emitted the duplicate.
- Validate again before formatting or converting.
- Add schema or application tests for the meaning of the retained value.
RFC 8259, Section 4: Objects — The primary JSON specification recommends unique object names and explains that duplicate behavior is unpredictable across implementations.