JSON Unicode escapes, newlines, and literal backslashes
Escaped text can represent the same value as readable text. Decode once before deciding whether a character is damaged.
An escape and a visible character can be equivalent
In JSON, a Unicode escape such as \u00f3 represents a character inside a string. It is not necessarily damaged text. These two documents encode the same city value:
{"city":"Le\u00f3n"}
{"city":"León"}The two lines above are separate documents for comparison, not a single JSON document to paste together. In Diff Checker, put one on each side: a JSON comparison sees the decoded values rather than the spelling of the escape.
import json
escaped = r'{"city":"Le\u00f3n"}'
readable = '{"city":"León"}'
print(json.loads(escaped) == json.loads(readable))
print(json.dumps(json.loads(escaped), ensure_ascii=False))Expected output:
True
{"city": "León"}ensure_ascii=False changes how the encoder writes non-ASCII characters. It does not change the decoded value or choose the encoding used when you later write a file.
A newline escape is not the same as backslash plus n
A JSON string cannot contain an unescaped literal line break. It can contain the escape \n, which decodes to a newline. To store the two literal characters backslash and n, JSON must escape the backslash itself.
import json
newline = json.loads(r'{"message":"first\nsecond"}')["message"]
literal = json.loads(r'{"message":"first\\nsecond"}')["message"]
print(len(newline.splitlines()))
print(len(literal.splitlines()))
print(newline == literal)Output:
2
1
FalsePython raw strings in this recipe keep Python from interpreting the backslashes before the JSON decoder sees them. When reading a file or HTTP body, that extra source-code string-literal layer is absent. Keep those layers separate when reproducing a bug.
Fix the byte encoding where the text enters the program
UTF-8 is a byte encoding; JSON escapes are part of JSON's text syntax. If a file displays mojibake such as León, changing JSON indentation or removing escape sequences will not address how the bytes were decoded. Verify the producer's encoding and read the source with the matching decoder.
For a UTF-8 JSON file in Python, open it with encoding="utf-8" before calling json.load(). If the text was already decoded incorrectly upstream, obtain the original bytes when possible. Avoid a blanket “encode then decode” repair across all fields: it can corrupt characters that were already correct.
The JSON interoperability rules specify UTF-8 for exchange outside closed ecosystems. A local legacy export still needs its actual encoding identified before conversion.
Inspect values and keep the original representation
Open a sample with Unicode, a newline, and a Windows-style path. Press Convert, then switch between the editor and tree to inspect the values. The tool parses before serializing, so escape spelling can change even when string content does not.
If a task requires the exact original spelling of every escape or source byte, retain the raw input separately. Formatting is a reserialization step, not a byte-for-byte archive. If the whole document is a quoted string containing another document, diagnose double encoding instead of stripping its backslashes.