Developer

JSON Formatting and Validation: Syntax Rules, Common Errors and Fixes

Why a file that looks fine will not load. The ten mistakes behind most broken JSON, how to escape text, when to minify, and how to move data between CSV and JSON.

JSON Formatting and Validation: Syntax Rules, Common Errors and Fixes
Photo by Bibek ghosh on Pexels

Key takeaways

  • JSON is stricter than JavaScript. Use double quotes only. No comments, no trailing commas, no undefined, NaN or Infinity.
  • Most broken files fail for one of ten reasons. A validator that shows the character position finds the problem in seconds.
  • Pretty-print for people and version control. Minify anything sent over the network, and let gzip do the rest.
  • Inside a JSON string, escape double quotes and backslashes. Write line breaks as \n instead of pressing Enter.
  • CSV to JSON turns every value into text unless you say otherwise. Nested JSON needs a few choices before it fits into CSV.

JSON often fails to load for a small number of reasons. Almost all of them come from treating it like JavaScript. Think of a trailing comma, a single-quoted string, a comment or a key with no quotes. A validator that shows the exact character position finds the problem in seconds. The fix is usually one character. This guide sets out the rules and the ten errors behind most broken files. It shows how to escape text safely and when to pretty-print or minify. It also shows how to move data between CSV, YAML and JSON without losing anything.

The syntax rules on one page

JSON has six kinds of value and nothing else: object, array, string, number, the words true and false, and null. Everything in JSON is built from those.

  • An object is a set of key and value pairs inside braces: {"name": "Ada", "age": 36}. Keys are always text in double quotes. Pairs are split by commas. Do not put a comma after the last one.
  • An array is a list inside square brackets: [1, 2, 3] or ["red", "green"]. The items can be of mixed types.
  • A string is text in double quotes. Single quotes are not allowed. Some characters inside need a backslash in front. We cover that below.
  • A number is written in plain decimal: 42, -3.5, 1.2e10. No leading zeros (007 is wrong). No hexadecimal. No + sign in front. No NaN or Infinity.
  • true, false and null are all lowercase. True, NULL and undefined are errors.
  • Spaces between the parts are ignored. So a file can be one long line or neatly indented, and it means the same thing.
  • There are no comments. None. Not //, not /* */, not #.

A document is one value at the top level. It is usually an object or an array. The rules are small on purpose. That way every language reads JSON the same way. A parser (the code that reads the text) refuses anything outside the rules instead of guessing.

The ten errors behind most invalid JSON

Each of these is legal in JavaScript, YAML or some config file. That is why they keep turning up.

1. A trailing comma

{"a": 1, "b": 2,} fails because of the comma after 2. The same goes for [1, 2, 3,]. Fix: delete the last comma. This is the most common error in hand-edited JSON. Many JavaScript tools like trailing commas, so people add them by habit.

2. Single quotes

{'name': 'Ada'} is a Python dictionary or a JavaScript object. It is not JSON. Fix: change every single quote around keys and values to a double quote. Be careful with find and replace. If the text has an apostrophe, such as "O'Brien", leave it as it is.

3. Comments

Lines that start with // or blocks in /* */ are common in config files that look like JSON. Some tools accept them. Standard JSON rejects them. Fix: remove the comments. Or put the note in a key such as "_comment", if the program reading it ignores keys it does not know.

4. Unquoted keys

{name: "Ada"} works in JavaScript. In JSON every key must be in double quotes, like "name". Fix: add the quotes. Python says it clearly: Expecting property name enclosed in double quotes.

5. A missing comma

Two pairs sit on back-to-back lines with no comma between them. This often happens after you paste in a new value. The parser reaches the second key and reports an unexpected string. Fix: add a comma at the end of the line above. A formatter that marks the error position takes you straight there.

6. Mismatched brackets or braces

An object ends with ], an array ends with }, or there is one more opening bracket than closing. The error is often reported at the very end of the file. That can be far from the real mistake. Fix: pretty-print the document. With neat indents, the bracket without a partner is easy to see.

7. A real line break inside a string

You may press Enter inside a string, for example when you paste an address or a paragraph. That puts a raw newline in the text, and JSON does not allow it. Tabs have the same problem. Fix: swap the line break for the two characters \n. Swap the tab for \t.

8. Unescaped backslashes

Windows paths and regular expressions are the usual cause. "C:\Users\ada" must be written "C:\\Users\\ada". Each backslash is doubled. A single backslash before a letter that is not a valid escape, such as \U, is an error. Fix: double every backslash you mean literally. Or run the text through an escaping tool.

9. JavaScript values that are not JSON

undefined, NaN, Infinity, new Date(), functions and hexadecimal numbers show up when you print an object with console.log. They do not show up when you use JSON.stringify. Fix: use null for missing values. Use a string for dates, ideally in ISO 8601 form, such as "2026-10-27T09:30:00Z". Use plain decimal numbers.

10. Hidden characters from a word processor or export

These come in three kinds. One is smart quotes (“ and ”) pasted from a document in place of straight quotes. Another is a byte order mark, a hidden mark at the start of a file that some Windows editors add. The third is non-breaking spaces. The file looks perfect and still fails on the first character. Fix: paste the text into a validator, which shows the bad position. Then replace the smart quotes. Save the file as UTF-8 without a BOM.

Duplicate keys, such as two "id" entries in one object, are not a syntax error. But most parsers quietly keep the last one. If a value seems to vanish, check for a repeated key first.

Structured code on a developer monitor
Photo by Nemuel Sereti on Pexels

Finding the error quickly

Error messages differ by language, but they all give you a position. Chrome and Node report Unexpected token with a character offset. Firefox gives a line and column. Python gives the line, column and character index. PHP returns Syntax error from json_last_error_msg() and leaves you to find the spot.

The method is the same in every case. Paste the text into the JSON Formatter and Validator. It pretty-prints the document and marks the line where reading stopped. The real mistake is usually on that line or the one before it. A parser only sees a missing comma when it reaches the next token.

Say a large file fails at the very end. Suspect a bracket that was never closed. Delete half the document and close the brackets by hand. Then check each half in turn.

Pretty-print or minify?

Both forms hold the same data. Pretty-printing adds line breaks and indents so people can read it. Minifying removes every extra space so machines can send it fast. Neither one changes a single value.

SituationUseWhy
Config files, fixtures, anything in version controlPretty-printed, 2-space indentEasy to compare; a change to one key shows as one line
Reviewing an API responsePretty-printedYou can see the nesting; errors are easy to spot
API responses in productionMinifiedSmaller payloads and less work for the client
Data inside an HTML page or script tagMinifiedKeeps the page small
LogsMinified, one record per lineEach line is a full document that tools can search and stream

Minifying does save space. But the saving is smaller than people expect once compression is used. Indents usually add 20 to 40 percent to a file. Gzip removes most of that again, because repeated spaces compress very well. So the honest advice is simple. Minify what goes over the network, because it costs nothing. Pretty-print everything a person will open.

Example. A 400-record product export is 96 KB pretty-printed with 4-space indents and 61 KB minified. Gzipped, the two become 9.8 KB and 8.9 KB. The 35 KB gap on disk shrinks to under 1 KB on the wire.

A software developer working late at a desk
Photo by Zayed Hossain on Pexels

Escaping strings for JSON

A JSON string starts and ends with a double quote. So some characters could be mistaken for the end of the string. Others cannot be typed as plain characters. You write these with a backslash in front. This is called escaping.

CharacterWrite it asNotes
Double quote "\"Required
Backslash \\\Required; the usual problem in file paths
Newline\nRequired; raw line breaks are not allowed
Carriage return, tab\r, \tRequired
Forward slash /\/ or /Optional; escaping it only helps inside HTML script tags
Any character\u00e9Four hex digits; rarer characters such as emoji use a pair like \ud83d\ude00
Single quote ''No escape needed, and \' is invalid

The hard case is JSON inside JSON. A webhook may carry another document as a string. A config value may itself be JSON. The inner document must be escaped once for each level. Take {"a": 1} stored as a string value. It becomes "{\"a\": 1}". If that is placed inside another string, every backslash and quote doubles again. Doing this by hand is easy to get wrong. Paste the text into the JSON Stringify Text Generator. It gives back the string with the right quotes and escapes, ready to drop into the outer document.

Now the other direction. A value may look like "line one\nline two". The \n is two characters in the file. It becomes one newline once the text is read. Suppose you see a literal backslash and n in your app output. Then the text was escaped twice and read only once.

Converting between CSV and JSON

CSV and JSON store data in different ways. CSV is a flat grid. Every row has the same columns, and every cell is text. JSON can nest objects inside objects and arrays inside arrays. It also tells numbers, booleans and null apart from text. Going one way is easy. Going the other way needs a few choices.

CSV to JSON

The first row becomes the keys. Each later row becomes one object in an array:

sku,name,price,in_stock followed by A100,Desk lamp,24.99,true becomes [{"sku": "A100", "name": "Desk lamp", "price": "24.99", "in_stock": "true"}]

Notice that price and in_stock came out as strings. CSV has no types. So a converter either leaves everything in quotes or makes a guess. The CSV to JSON and JSON to CSV Converter can spot numbers and booleans. Then 24.99 becomes a number and true becomes a boolean. Check that postcodes, phone numbers and product codes with leading zeros stay as strings. If 01234 turns into 1234, you lose data. This is a real and common problem.

Also check the separator. European exports often use semicolons. Watch for a blank last line, which can become an empty object.

JSON to CSV

Flat arrays of objects convert cleanly. The keys become the header row. Missing keys leave empty cells. Nested data is harder. Take {"name": "Ada", "address": {"city": "London", "postcode": "N1"}}. It has to be flattened into columns like address.city and address.postcode. A list of tags has two options. You can join it into one cell with a separator. Or you can give each tag its own row. Decide which you want before you convert. Then check the first few rows of the result.

YAML and JSON

In practice YAML is a superset of JSON. Any JSON document is valid YAML. But YAML also allows comments, unquoted strings, multi-line text and anchors (named reusable blocks). Turning YAML into JSON drops the comments and fills in every anchor. Turning JSON into YAML keeps the data and makes it easier to read. The YAML to JSON Converter works both ways. It is a quick way to turn a commented config file into strict JSON that an API will accept.

Troubleshooting table

Error message (approximate)Likely causeFix
Unexpected token } or Unexpected token ]Trailing comma before the closing bracketDelete the comma
Expecting property name enclosed in double quotesUnquoted or single-quoted key, or a trailing comma in an objectPut the key in double quotes
Unexpected token ' or Unexpected stringSingle-quoted string, or a missing comma before itUse double quotes; add the comma
Unexpected token / or Unexpected token #A commentRemove it
Unexpected end of JSON inputUnclosed bracket, brace or string; cut-off filePretty-print and match the brackets; check the file was fully saved
Bad control character in string literalRaw newline or tab inside a stringReplace with \n or \t
Bad escaped characterA backslash before an invalid letter, often in a Windows pathDouble the backslash
Unexpected token u or Nundefined or NaN in the dataUse null or a number
Unexpected token at position 0, file looks fineByte order mark or smart quotesSave as UTF-8 without BOM; replace curly quotes
Malformed UTF-8File saved in another encoding, such as Windows-1252Save it again as UTF-8

Where to go next

Paste anything that will not load into the JSON Formatter and Validator. You will see the error position and get a tidy copy with indents, or a minified one. Use the JSON Stringify Text Generator when text, a path or a whole document must become a safe string value. For spreadsheet data, the CSV and JSON converter goes both ways. The YAML to JSON Converter turns commented config into strict JSON. All of them run in the browser, so your data stays on your machine.

Frequently asked questions

Why is my JSON invalid when it looks correct?

The usual causes are a comma after the last item, single quotes instead of double quotes, a comment, or hidden characters such as smart quotes pasted from a document. Run the text through a validator that shows the character position. The mistake is almost always on the reported line or the one before it. The fix is normally a single character.

Does JSON allow comments?

No. Standard JSON has no comment syntax at all. Lines that start with // or blocks in /* */ cause an error. Some tools accept a relaxed form with comments, but anything you send to an API must be free of them. If you need a note, put it in a key such as "_comment" that your program ignores. Or keep the file in YAML and convert it to JSON when needed.

Should I use single or double quotes in JSON?

Always use double quotes, for both keys and text values. Single quotes are not part of JSON, and every strict parser rejects them. JavaScript and Python accept them in their own syntax, but that does not count. An apostrophe inside a string, such as O'Brien, needs no escape. Only double quotes and backslashes inside a string must be escaped.

Is minified JSON faster than pretty-printed JSON?

Slightly, but less than you might expect. Minifying removes spaces, so fewer bytes travel and the parser skips fewer characters. Once the response is gzipped, the gap shrinks to a small fraction, because runs of spaces compress very well. Minify what you send over the network. Pretty-print anything a person will read or keep in version control.

How do I put a line break inside a JSON string?

Write it as the two characters backslash and n, like "first line\nsecond line". A real line break typed with the Enter key is a control character. JSON does not allow it inside text, and the parser reports a bad control character. The same goes for tabs, which you write as backslash and t. An escaping tool does this for you when you paste text.

Why did my numbers turn into strings when converting CSV to JSON?

CSV has no data types. Every cell is text, so a careful converter puts every value in quotes. Turn on type detection if you want 24.99 to become a number and true to become a boolean. But check columns that only look like numbers. Postcodes, phone numbers and product codes with leading zeros should stay as strings. Turning 01234 into 1234 quietly damages the data.

Try the tools from this guide

Keep reading

Related guides

All guides