Data formats

How to fix invalid JSON: the common errors

Trailing commas, single quotes, unquoted keys, comments and NaN break JSON. See each error before and after, and learn to read "Unexpected token" messages.

Sanjeev Maharjan5 min read

Most invalid JSON comes from writing it like JavaScript: a trailing comma after the last item, single quotes instead of double, keys without quotes, comments, or values such as NaN and undefined. Find the position the error message gives you, look just before it for one of these, fix it, and parse again. Repeat until it passes.

The short version: JSON is stricter than JavaScript. Strings and keys need double quotes, no trailing commas, no comments, and only true, false, null, numbers, strings, arrays and objects as values.

The rules JSON actually has

JSON is a small format and its rules are short. A value is one of: a string in double quotes, a number, true, false, null, an array in square brackets or an object in curly braces. Object keys are always strings in double quotes. Items are separated by commas, with no comma after the last one. That is nearly all of it.

Because JSON looks like JavaScript, people write it the way JavaScript allows, and JavaScript allows a lot that JSON does not. Every error below comes from that gap.

The common errors, before and after

Trailing commas

A comma after the last item in an array or object is the most common mistake of all.

{ "name": "Ada", "langs": ["en", "fr",], }
{ "name": "Ada", "langs": ["en", "fr"] }

Single quotes

JSON strings use double quotes only. A single quote is not a string delimiter at all.

{ 'name': 'Ada' }
{ "name": "Ada" }

Unquoted keys

JavaScript lets you write { name: "Ada" }. JSON does not.

{ name: "Ada", age: 36 }
{ "name": "Ada", "age": 36 }

Comments

Standard JSON has no comments, neither // nor /* */. Some tools accept them in config files (often called JSONC), but a strict parser will not. Remove them, or move the note into a field such as "_comment" if you really need it.

{
  // the port to listen on
  "port": 8080
}
{ "port": 8080 }

NaN, Infinity and undefined

These are JavaScript values, not JSON ones. JSON.stringify turns NaN and Infinity into null and drops undefined fields, but hand-written or Python-generated JSON sometimes contains them as bare words.

{ "score": NaN, "limit": Infinity, "note": undefined }
{ "score": null, "limit": null }

Unescaped control characters

A real line break or tab inside a string is not allowed. It must be written as an escape: \n for a new line, \t for a tab, \" for a quote and \\ for a backslash. This often happens when text is pasted from a log or an editor.

{ "msg": "line one
line two" }
{ "msg": "line one\nline two" }

Windows paths catch people out the same way: "C:\\Users" must be written with the backslash doubled.

How to read "Unexpected token at position" errors

When JSON.parse fails in a browser or Node, it says something like Unexpected token } in JSON at position 42, or in newer engines, a message naming the character and the position. Other parsers give a line and column instead. Either way, the number tells you where the parser gave up, which is usually just after the real mistake.

  1. Go to that position, or that line and column.
  2. Look at the character there and the one or two before it.
  3. A } or ] right after a comma means a trailing comma. A ' means single quotes. A letter where a key should start means an unquoted key.
  4. "Unexpected end of JSON input" means something was not closed: a missing }, ] or closing quote, or the text was cut off.

Position counts characters from zero, so a long single-line payload is easier to fix once it has been beautified onto separate lines, where the line and column point straight at the problem.

If the JSON is wrapped in something else, such as a JWT payload or a Base64 string from an API, decode it first. The guide on Base64 on a Mac shows how. If the trouble is a date that looks wrong rather than invalid syntax, see converting a Unix timestamp.

Beautify or minify

Both produce the same data. They differ only in whitespace.

  • Beautify (also called pretty print or format) puts each item on its own line with indentation. Use it to read, review and debug. JSON.stringify(value, null, 2) does this in JavaScript, and python3 -m json.tool file.json does it in Terminal.
  • Minify removes every space and line break that is not inside a string. Use it to send or store JSON where size matters. JSON.stringify(value) gives minified output.

Sorting keys is a third useful step when comparing two versions of the same data, because it makes the order the same on both sides.

How DailyUtil does it

DailyUtil's JSON Format tool is free and runs offline on your Mac. It beautifies, minifies and sorts keys, and when the JSON is invalid it shows the error with its line and column so you can go straight to it. With AI turned on, Fix proposes a corrected version and shows you the change before it replaces your input, with Undo if you change your mind. The AI can run on Apple Intelligence on the Mac, or on your own key for a cloud provider. You can download DailyUtil and see the full list of tools on the features page.

Questions people ask

Why does JSON not allow trailing commas?

The JSON grammar was kept deliberately small, and it simply has no rule for a comma after the last item. Some parsers are lenient, but strict ones reject it, so remove the comma to be safe everywhere.

Can JSON have comments?

Standard JSON cannot. Some tools read a variant called JSONC that allows them in config files, but an ordinary parser will fail. If you need a note inside data, store it as a normal string field.

What does "Unexpected end of JSON input" mean?

The parser reached the end of the text while still expecting more. Usually a closing brace, bracket or quote is missing, or the response was empty or cut off before it finished arriving.

Does beautifying JSON change the data?

No. Beautifying and minifying change only whitespace outside strings. The keys, values and structure stay exactly the same, so either form parses to identical data.

Share this guide

XLinkedInEmail

Written by Sanjeev Maharjan

Sanjeev Maharjan builds DailyUtil, developer tools for the Mac. Found a mistake in this guide? Write to [email protected].

Keep reading

More guides

Data formats

How to Base64 encode and decode on a Mac

What Base64 is, how it differs from Base64URL, and the Terminal commands that encode and decode it on macOS without surprises.

5 min read

Data formats

How to convert a Unix timestamp to a date

Seconds or milliseconds, UTC or local time: how to turn a Unix timestamp into a real date on a Mac, on Linux and in JavaScript.

5 min read

Tokens and security

How to decode a JWT safely, without a website

Read the header and payload of a JWT offline, make sense of exp, iat and nbf, and know what decoding does not prove.

5 min read

Get DailyUtil

Put the toolbox on your Mac

Free for eight tools, with no time limit and no account. Needs macOS 14 or later on Apple Silicon and Intel.