Data format interoperability means that independent producers and consumers can exchange data with an agreed interpretation. Sharing a syntax is one part of that agreement; character encoding, supported values and handling of ambiguous inputs also matter. Serialization and deserialization must preserve the distinctions the application needs.[ref]
Consider the original JSON input {"mode":"fast","mode":"safe"}. RFC8259 says object member names should be unique and warns that duplicate-name handling differs. In Python, the default json.loads result is {'mode': 'safe'}. The same decoder with object_pairs_hook=list instead returns [('mode', 'fast'), ('mode', 'safe')], preserving both pairs.[ref][ref]
The text has not changed, yet one consumer retains one value and another retains both occurrences. Re-encoding the default dictionary cannot recover the discarded occurrence. A consumer can instead use a hook that rejects a repeated name, making the ambiguity explicit before the application acts on it.
An exchange contract can therefore require unique names and a shared duplicate-rejection policy, as well as a character encoding such as UTF-8. That is a stronger agreement than merely saying that both programs support JSON. Data validation then checks application-level requirements on the agreed decoded representation.
Deserialization 2026-11-05
Deserialization reconstructs values from a representation produced according to a format such as JSON. The decoder's mapping determines the resulting runtime data types. In Python, json.loads maps a JSON object to a dictionary, an array to a list, false to False and null to None by default.[ref]
For an original example, json.loads('{"enabled":false,"items":[null,0,"0"]}') produces {'enabled': False, 'items': [None, 0, '0']}. The last two items differ: the integer zero and a string containing a digit are not interchangeable. The decoder reconstructs nested values rather than returning the displayed source text.
Syntax and application meaning require separate checks. The malformed JSON {"items":[1,2,]} raises JSONDecodeError. By contrast, {"items":"many"} parses successfully but fails a program's requirement that items be a list. That second check is data validation, beyond recognizing the format's syntax.[ref]
Nor does successful deserialization guarantee recovery of every original property. A Python tuple encoded as a JSON array normally returns as a list. A round-trip claim must specify whether it preserves values, runtime types or object identity. Character encoding and parsing contribute to the reconstruction, while the selected mapping determines which distinctions survive.