Articles
Parseable JSON is Not Always Valid or Consistent JSON
Parsing behavior is undefined and implementation-dependent
I discovered something interesting while troubleshooting a JSON-related issue that another ColdFusion developer created.
Consider the following JSON:
{
"question_1": "What is your name?",
"question_1": "What is your email?"
}
Regarding JSON validity, Claude.ai states:
The JSON specification (RFC 8259) says that object keys SHOULD be unique, but it doesn't strictly forbid duplicates-meaning duplicate keys produce valid JSON that will parse, but the behavior is undefined and implementation-dependent.
In practice:
- Most parsers will accept duplicate keys without error, but they'll only keep one value (typically the last one)
- Some parsers might keep the first, others the last
- A few strict parsers will reject it outright or throw a warning
So while {"name": "Alice", "name": "Bob"} is technically parseable JSON, it's considered bad practice and effectively invalid for interoperability purposes. You can't rely on consistent behavior across different languages and libraries.
If you're generating JSON, you should always ensure unique keys. If you're consuming JSON and encounter duplicates, the safest assumption is that the behavior is unpredictable.
So how do various CFML platforms and other technologies behave?
Adobe ColdFusion 10-2025: Only retains the last declared key.
Railo: Only retains the last declared key.
Lucee 4-7: Only retains the last declared key.
Boxlang: isJson() fails. Attempts to use deserializeJson() throws a "Failed to parse JSON" error.
JSONUtil CFC: Throws a "Cannot insert item with key question_1" error.
Microsoft SQL JSON_VALUE query: Only retains the first declared key.
Web-based Javascript Utilities: Only retains the last declared key.
JSON Crack: Only diagrams the last declared key.
JSONedit: Only renders and allows editing of the the last declared key.
MiTeC JSON Viewer x64: Displays both keys. Doesn't seem to mind. No data loss when viewing or editing.
So what do I do as a cross-platform CFML developer?
Most isJson() functions will blindly accept duplicate keys and return TRUE as they are only parsing the syntax and not inspecting any content. Boxlang is strict and does not allow duplicate keys.
Since I prefer to always error on the side of caution and require that results be consistent across multiple systems, I will continue to use the third-party JSONUtil CFC (from 2009) when serializing & deserializing JSON. It may not be as fast as using the built-in functions, but it is safer IMHO.