Common JSON Errors and How to Fix Them
JSON looks like JavaScript but follows much stricter rules. Here are the mistakes that break a parser most often, each with a broken example, the fix and the reason behind it.
By the Fileora team7 min read
A config file refuses to load, an API returns a 400, or a script stops with "Unexpected token". Nine times out of ten the cause is one small character that JSON does not allow. The rules are short and strict, so once you know them the fixes take seconds.
The rules below come from RFC 8259, the standard that defines JSON. Each section shows the broken version first and the fixed version second.
Find the exact spot first
Before hunting by eye, paste the text into the JSON formatter. If the JSON is invalid, it reports the line and column at which the parser gave up, gives a plain-English explanation such as "JSON doesn't allow comments", and repeats that line with a caret (^) pointing at the bad character. It uses the parser built into your browser and nothing is uploaded, so pasting a response that contains customer data or tokens is fine.
A word on error messages: the text of a JSON.parse error is not standardised, so it differs between browsers and versions. The same trailing comma that Node.js reports as "Expected double-quoted property name" appears in MDN's reference as "unexpected character". Treat any quoted message below as an example, not something to search for word for word. The position is more useful than the wording.
1. Single quotes
Every string and every key in JSON sits inside double quotes. Single quotes are fine in JavaScript and Python, which is why they sneak in when people type JSON by hand.
Broken:
{'name': 'Ayesha'}
Fixed:
{"name": "Ayesha"}
2. Keys without quotes
An object key is always a string, so it needs quotes too, even when it is a simple word.
Broken:
{name: "Ayesha", age: 31}
Fixed:
{"name": "Ayesha", "age": 31}
3. Trailing commas
A comma after the last item of an object or array is the single most common JSON error. Modern JavaScript accepts it; JSON never has.
Broken:
{"tags": ["pdf", "image",], "active": true,}
Fixed:
{"tags": ["pdf", "image"], "active": true}
It often appears after you delete the last line of a list and forget the comma on the line above. The opposite mistake, a missing comma between two items, produces an "expected ',' or '}'" style error.
4. Comments
JSON has no comment syntax at all, neither // nor /* */.
Broken:
{
"port": 8080 // default port
}
Fixed:
{
"port": 8080,
"_comment": "default port"
}
If you need a note, put it in a normal field that your program ignores, or keep the documentation elsewhere.
5. Wrong literals: True, None, NaN, undefined
JSON has exactly three literal words: true, false and null, and the standard says they must be lowercase. Values copied from other languages break this rule: Python prints True and None, and JavaScript has undefined, NaN and Infinity. None of them are valid JSON.
Broken:
{"paid": True, "discount": None, "score": NaN}
Fixed:
{"paid": true, "discount": null, "score": null}
For a value that could not be calculated, null is the usual choice. That is also what JavaScript's own JSON.stringify does: according to MDN it writes NaN and Infinity as null, and silently drops object properties whose value is undefined. If a field disappears after a round trip, that is the likely reason.
6. Numbers written the wrong way
JSON numbers are plain decimals. The grammar in RFC 8259 rules out several forms that programming languages accept:
- no leading zeros (
007is invalid;0.7and0are fine) - no plus sign in front (
-5is allowed,+5is not) - no hexadecimal (
0x1F) - no bare decimal point at either end (
.5or5.)
Broken:
{"code": 007, "offset": +5, "mask": 0x1F, "ratio": .5}
Fixed:
{"code": "007", "offset": 5, "mask": 31, "ratio": 0.5}
Notice the first fix: if the leading zeros matter, as with postcodes, phone numbers and product codes, the value is really text and belongs in quotes.
7. Characters inside strings
A string cannot contain a raw line break or tab. The standard requires the double quote, the backslash and all control characters (U+0000 to U+001F) to be escaped. The escapes you are allowed are \", \\, \/, \b, \f, \n, \r, \t and \uXXXX with four hex digits.
Windows paths are the classic trap, because every backslash has to be doubled:
Broken:
{"path": "C:\temp\new", "quote": "She said "hi""}
Fixed:
{"path": "C:\\temp\\new", "quote": "She said \"hi\""}
In the broken line, \t and \n are valid escapes that quietly turn into a tab and a line break, so the parser may not even complain. That makes this one worth checking by eye.
8. Smart quotes from a word processor
Word, Google Docs, Pages and many chat and email apps replace straight quotes (") with curly ones (“ ”) as you type. They look almost the same, but a parser sees a completely different character and stops. The formatter reports it as an unexpected character and shows it to you.
The fix is to retype the quotes in a plain-text or code editor, or turn off "smart quotes" in the app before copying. Better still, never keep JSON in a word processor document.
9. An invisible BOM at the start
Some Windows programs save UTF-8 files with a byte order mark: an invisible character, U+FEFF, at the very start. RFC 8259 says programs must not add one to JSON sent over a network, and that parsers may ignore it rather than treat it as an error. Many do not ignore it: in our test, JSON.parse in Node.js, which runs on the same V8 engine as Chrome, rejected a string that began with one.
The symptom is an error at line 1, column 1 on a file that looks perfect. Re-save it as "UTF-8" rather than "UTF-8 with BOM"; most code editors show the encoding in the status bar.
10. JSON5 and JSONC are not JSON
Many config files look like JSON but are read by a more relaxed parser:
- JSONC ("JSON with Comments") is what VS Code uses for files such as
settings.json,tasks.jsonandlaunch.json. Its documentation says it accepts//and/* */comments, and trailing commas with a warning. - JSON5 goes further: comments, trailing commas, single quotes, unquoted keys, hexadecimal, a leading plus sign, and
NaNandInfinity.
Both are fine where the program expects them. Problems start when you copy a snippet from such a file into an API request, a package.json or a strict validator. If a file loads in one place and fails in another, check which format each side expects before changing anything.
11. Big numbers that quietly change
This one produces no error at all. JavaScript stores every number as a 64-bit float, and MDN gives the largest integer it can hold exactly as 9,007,199,254,740,991 (Number.MAX_SAFE_INTEGER, 2^53 - 1). Anything bigger may be rounded to a nearby value when parsed:
{"id": 9007199254740993}
In a browser, JSON.parse turns that into 9007199254740992. RFC 8259 itself warns that only integers in that range are reliably interchangeable. Long IDs from databases and social platforms regularly exceed it, so send them as strings:
{"id": "9007199254740993"}
Spreadsheets have a similar issue with long numbers. The CSV to JSON converter only turns a cell into a JSON number when its value lies strictly between -2^53 and 2^53; anything outside that stays as text. Switch number conversion off entirely if you want every ID kept exactly as typed.
After the fix: converting the data
Once the JSON is valid, you may want it in a spreadsheet. The JSON to CSV converter takes an array of objects, one per row, and can flatten nested fields into columns such as address.city. It uses the browser's own parser, so any of the errors above will stop it too, with the browser's message shown. Check the file in the formatter first if it refuses to convert.
Quick checklist
- Double quotes around every key and every string, and straight quotes, not curly ones.
- No comma after the last item in any object or array.
- No comments, unless the file is meant to be JSONC or JSON5.
- Only
true,falseandnull, all lowercase. - Numbers without leading zeros, plus signs or hex; codes with leading zeros in quotes.
- Backslashes, quotes and line breaks inside strings escaped.
- Saved as UTF-8 without a BOM.
- IDs of 16 digits or more sent as strings.
Work through the list from the position the parser reports, fix one problem at a time and re-check. One error often hides the next, because a parser stops at the first character it cannot make sense of.