# Why your JSON will not parse, and how to find the bad comma

> “Unexpected token at position 214” tells you almost nothing. Here is what a parser is really doing, the handful of mistakes behind nearly every error, and why the real problem is often just before the place it points to.

Published 2026-10-07 by Toolcloak. 3 minute read. Original: https://toolcloak.pages.dev/articles/why-your-json-wont-parse-and-how-to-find-the-bad-comma
Related free tool: [JSON Formatter](https://toolcloak.pages.dev/tools/json-formatter)

It is late, the deploy is blocked, and the log says one thing: unexpected token } in JSON at position 214. You open the file. It is 300 lines long and looks perfectly fine. Welcome to the most common small frustration in software.

The good news is that JSON is a tiny, strict language. There are only a few ways to break it, and once you know them you can spot most errors by eye in seconds.

## What JSON allows, in one paragraph

A JSON value is one of six things: a **string** in double quotes, a **number**, `true` or `false`, `null`, an **array** in square brackets, or an **object** in curly braces whose keys are strings in double quotes. Items are separated by commas. That is the entire language. No comments, no extras, no shortcuts.

## Looks fine in JavaScript, breaks in JSON

Most errors come from people writing JavaScript-style data and assuming it is valid. It is close, and close is not enough.

| You wrote | Why it fails | Write this instead |
| --- | --- | --- |
| {'name': 'Asha'} | Single quotes are not allowed | {"name": "Asha"} |
| [1, 2, 3,] | Trailing comma after the last item | [1, 2, 3] |
| {name: "Asha"} | Keys must be in double quotes | {"name": "Asha"} |
| // note | JSON has no comments | Remove it, or add a "note" field |
| {"a": undefined} | undefined is not a JSON value | Use null, or leave the key out |
| {"id": 007} | Numbers cannot have leading zeros | 7, or the string "007" |
| {"x": NaN} | NaN and Infinity do not exist | null, or a string |

*If you copy an object out of code or a log and paste it somewhere that wants JSON, check this list first.*

## Why the error points to the wrong place

A parser reads characters from left to right and stops at the first one that cannot be right. Crucially, it reports where it **gave up**, not where you made the mistake. In most parsers, position counts characters from zero at the start of the text.

Say you forget a comma between two fields. The parser happily reads the first value, then meets the next key, which should have been preceded by a comma. It complains about that key. The real mistake is the empty space right before it. The same happens with a missing closing quote or bracket: the error appears further down, where the structure finally stops making sense.

**What a parser does with your text**

1. **Read.** Go through the characters one by one from the start.
2. **Split into tokens.** Recognise strings, numbers, brackets, commas and colons.
3. **Check the grammar.** Each token must be allowed at that spot. A comma before a closing bracket is not.
4. **Build or stop.** If everything fits you get an object. At the first misfit it stops and reports it.

> **Rule of thumb:** When the error points at a token, look at the character just before it first. A missing comma, an extra comma or an unclosed quote is usually sitting there.

Try it: [JSON Formatter](https://toolcloak.pages.dev/tools/json-formatter). Paste your JSON to validate, indent and minify it, with the problem line shown.

## Formatting and minifying

A formatter only changes whitespace. It adds line breaks and indentation so a human can read the structure, and a minifier removes them again so the data is as small as possible. The data itself does not change.

Here is one small object, with an indent of two spaces, four spaces, and none at all:

**The same object, three layouts (bytes)**

|  | Bytes |
| --- | --- |
| Minified | 82 B |
| Indented 2 spaces | 121 B |
| Indented 4 spaces | 145 B |

*Whitespace added roughly half again to this tiny object. On large API responses, sending minified JSON is a cheap way to save bandwidth, while indented JSON is better for files people read.*

## Three traps that are valid but still bite

- **Big numbers.** JavaScript stores numbers as 64-bit floats, so integers above 9,007,199,254,740,991 can silently change. Send long IDs as strings.
- **Dates.** JSON has no date type. Use a text format like `2026-10-07T09:30:00Z` and agree on it with whoever reads it.
- **Duplicate keys.** The format says keys should be unique, but parsers disagree on what to do. Many keep the last one. Do not rely on it.

> **Be careful what you paste:** JSON from real systems often holds tokens, emails or customer records. Use a formatter that runs in your browser and does not upload the text, and avoid pasting secrets into sites you do not trust.

## Frequently asked questions

### What does “unexpected token in JSON” mean?

The parser reached a character that is not allowed at that point. The real mistake is often just before it, such as a missing or extra comma, a single quote, or an unclosed bracket.

### Can JSON have comments?

No. Standard JSON does not allow comments. Remove them, or store the note as a normal field. Some tools accept a relaxed variant, but you cannot count on it.

### Are single quotes allowed in JSON?

No. Strings and keys must use double quotes. Single quotes are valid in JavaScript but not in JSON.

### What is the difference between formatting and minifying JSON?

Formatting adds line breaks and indentation to make JSON readable. Minifying removes all unneeded whitespace to make it smaller. Both keep the data exactly the same.

### Why does my large ID change after parsing?

Numbers above 9,007,199,254,740,991 cannot be stored exactly as a JavaScript number. Store such IDs as strings to keep every digit.

