Short answer: JSON breaks in a small number of ways — quotes, commas, brackets, escapes, and look-alike literals from other languages. A validator tells you *where* it broke and *what* the parser expected; this guide maps the exact messages to the exact fix. One honest scope note: the YYSI formatter validates, locates, formats, minifies, sorts and diffs — it does not auto-repair. You apply the fix yourself; that is safer, because a "repair" that changes syntax can also change meaning (think 007 becoming 7).
The error dictionary (all messages verified in the real tool)
Each row below was produced by pasting the sample into the live formatter and recording what its parser said. Positions are from that parser; other tools may point elsewhere — the *cause* and *fix* columns are what transfer.
| What you pasted | What the parser said (real) | Meaning → exact fix |
|---|---|---|
{'name': 'YYSI'} | Line 1, column 2: Expected object key | JSON strings use double quotes only → "name": "YYSI" |
{"a": 1, "b": 2,} | column 31: Expected object key | Trailing comma before } — the parser now expects another key → delete the last comma |
["news", "tools",] | column 18: Unexpected character "]" | Trailing comma in an array → delete it |
{"a": 1 "b": 2} | column 9: Expected "," or "}" | Missing comma between pairs → add , |
{"timeout" = 30} | column 12: Expected ":" after key | Assignment syntax → use : not = |
{"user": {"name": "Ada"... (one } missing) | column 33: Expected "," or "}" | A nested object never closed at EOF → add the missing } (when input simply stops mid-structure the message is Unexpected end of input) |
``json\n{...}\n`` (Markdown fence) | Line 1, column 1: Unexpected character "`" | Copy from a chat/LLM window → delete the fence lines, keep the JSON between them |
{"quote": "He said "hi" fast"} | column 21: Expected "," or "}" | The inner quote *ends* your string early → escape inner quotes: \"hi\" |
{"text": "line1␊line2"} (real newline) | column 16: Unescaped control character in string | Raw line breaks are invalid inside strings → write \n |
{“name”: “YYSI”} (curly quotes) | column 10: Unexpected character "“" | Word processors replace straight quotes with curly ones → retype as ASCII " |
{"delta": +1} | column 11: Unexpected character "+" | JSON numbers can't start with + → drop it |
{"zip": 007} | column 10: Expected "," or "}" | Leading zeros are forbidden in JSON numbers → if it is a code/ID, store it as a string: "007" |
{"mask": 0x1F} | column 11: Expected "," or "}" | No hexadecimal in JSON → write decimal 31 |
{"ok": True, "x": None} | column 8: Unexpected character "T" | Python literals → JSON uses lowercase true / false / null |
{"score": NaN} | column 11: Unexpected character "N" | NaN/Infinity are JavaScript, not JSON → use null or a real number |
{name: "YYSI"} (unquoted key) | column 2: Expected object key | Keys must be quoted strings → {"name": "YYSI"} |
// comment after or inside values | Expected "," or "}" (inside) / Unexpected trailing content (after a complete document) | JSON has no comments → move the note outside the data |
| empty input | Line 1, column 1: Unexpected end of input | Nothing to parse → the file may have been saved empty |
- Copy-paste sheet: all 18 invalid snippets, labeled — Download sample · 897 bytes
- Machine-readable record: bad text, fixed text, and the cause of each (bilingual) — Download sample · 5650 bytes
Step by step with the real tool
- Paste and read the status. Paste your text into the formatter. While you type it shows
Valid JSON · N bytesorInvalid JSON. - Press Format to locate the error. On invalid input the tool reports the position and the parser's complaint, e.g.
Error at line 1, column 1: Unexpected character ""` for a Markdown fence. Find that line/column in your text. - Match the message to the dictionary above. Apply the one-character or one-line fix. Re-format to confirm the error is gone — positions shift as you edit, so fix the *first* reported error, then retry.
- Format, minify or sort. Once valid: Format re-indents (2 spaces, 4 spaces or tab), Minify strips whitespace, Sort orders object keys alphabetically at every depth.
- Copy or download. Copy to clipboard or download
yysi-formatted.json. Both activate only after a successful parse. - Compare two versions. Paste the second JSON into the compare box and press Diff: changes, additions and removals are listed per path with array length changes — useful for checking that your fix changed nothing else.
Our real diff example
Diffing {"model": "flash", "retries": 3, "cache": true, "tools": ["search"]} against {"model": "pro", "retries": 3, "cache": false, "tools": ["search", "code"], "note": "nov"} produced exactly:
CHANGED $.model "flash" → "pro"
CHANGED $.cache true → false
CHANGED $.tools length 1 → 2
ADDED $.tools[1] "code"
ADDED $.note "nov"Strict JSON vs JavaScript object literal
Most "broken JSON" is actually a JavaScript object literal (or Python dict) — a different language. JSON (RFC 8259) allows neither single quotes, nor bare keys, nor trailing commas, nor comments, nor +/hex/leading-zero numbers, nor True/None. Editors and consoles accept those because they evaluate *code*, not *data*. If your text came from a JS/Python file, expect to convert all of these; if it came from a log, also expect unescaped quotes and raw newlines inside strings.
LLM output is its own genre
- Markdown fences (``
or`json) around the payload — the single most common error when copying from chat windows; our sample reproducesUnexpected character ""at column 1. - Trailing commas and single quotes — models imitate the training data's JavaScript.
- Comments explaining the fields — models narrate; JSON cannot.
- Fix order: delete fences → fix quotes/commas → remove comments → validate. Then re-paste the *final* value; never ship a fix you haven't re-parsed.
007 → 7 turns a part number into a different number, and deleting a trailing comma is fine but deleting a "duplicate" key is a data decision. Validate and fix deliberately; check numbers and IDs after any automated repair.Edges the tool tells you about honestly
| Input | What the tool does (verified) | Why it matters |
|---|---|---|
{"order_id": 9007199254740993} | Parses it, formats it, keeps the original digits and shows a warning listing the path (order_id) — because the value exceeds JavaScript's safe integer range (2^53−1) | Naive parsers silently turn …993 into …992; the warning tells you a downstream consumer may do exactly that |
{"a": 1, "a": 2} (duplicate keys) | Accepts the text; the later value wins ({"a":2}) — standard parser behavior, no warning | Duplicate keys are ambiguous data; if you did not write them on purpose, deduplicate by hand |
| Anything valid | Format / Minify / Sort are pure re-serialization — values, key order (except Sort) and number spelling are preserved | Formatting never changes meaning; sorting never changes values |
Limits
- The formatter is strict and offline: no repair, no schema validation, no network calls.
- Error positions are this parser's opinion; browsers, Python and other tools may point to different columns for the same broken text — treat positions as a starting hint, the message class as the truth.
- Everything runs in your browser tab; the text never leaves your device.
- Very large inputs are limited by browser memory like any text box; for multi-megabyte payloads use a local tool instead.
Related: turning fixed JSON tabular? JSON ↔ CSV converter — and if CSV then misbehaves in Excel, read the CSV garbled-Chinese troubleshooting guide.
Sources & verification
- RFC 8259 — the JSON grammar this guide checks against (double quotes, no comments, no leading zeros) — Sources checked 2026-11-11
- MDN JSON.parse — how the language's own parser differs from JavaScript object literals — Sources checked 2026-11-11
Sources checked The grammar rules summarized here come from RFC 8259 and MDN (checked 2026-11-11). Every error message, line/column position and behavior in the tables was produced by running the original sample set through the live YYSI JSON formatter's own parser on 2026-11-11 (18 invalid snippets + fixed pairs, plus format/minify/sort/diff/big-number demos). The samples are original synthetic text, published for reuse.
Read our editorial standards or send corrections to [email protected].