Try the JSON Formatter

Unexpected Token at Position 847: Debugging JSON Errors

"Unexpected token at position 847" has a short list of likely causes. Here's every JSON parse error, what triggers it, and the two that fail without throwing at all.

September 21, 2026 8 min read
Share: Facebook WhatsApp LinkedIn Email
Unexpected Token at Position 847: Debugging JSON Errors

The Error Message That Tells You Nothing

SyntaxError: Unexpected token } in JSON at position 847

Position 847. In a 12,000-character single-line payload. No line number, no context, no indication of what it expected instead.

JSON parsers are strict by design and terse by tradition. The good news is that the failure modes are a short, well-defined list — once you can recognise them, most errors resolve in under a minute.

Read the Position Marker First

Every JSON parse error gives you a character offset. Use it.

Paste the payload into the JSON Formatter:

  1. Paste the raw JSON.
  2. Format or validate.
  3. The tool reports where parsing failed.

Formatting a valid document splits it across lines and makes structure visible. Formatting an invalid one still gets you to the failure point faster than counting characters by hand.

The key insight about position numbers: the error is usually just before the reported position, not at it. A parser reads until something is impossible, then reports where it stopped. A missing comma at position 800 surfaces as an error at 847, where the parser encountered a token it couldn't reconcile.

Look backwards from the marker, not at it.

The Error List

Trailing comma

{
  "name": "widget",
  "price": 12.50,
}

The most common JSON error by a wide margin. Valid in JavaScript object literals, valid in Python dicts, invalid in JSON. Same for arrays:

["a", "b", "c",]

Symptom: error at the closing brace or bracket.

The reason it's so common is that most languages allow it, so the habit is deeply ingrained. Many linters can catch it before serialisation.

Single quotes

{'name': 'widget'}

JSON requires double quotes for both keys and string values. Single quotes are a Python and JavaScript habit.

Symptom: error at the first single quote.

A related case: unquoted keys.

{name: "widget"}

Valid JavaScript, invalid JSON. Keys must always be quoted strings.

Unescaped characters in strings

{"path": "C:\Users\data"}
{"quote": "She said "hello""}
{"text": "line one
line two"}

Three variants of the same problem. Inside a JSON string:

  • Backslash must be escaped as \\
  • Double quote must be escaped as \"
  • Literal newlines are not allowed — use \n
  • Tabs use \t, carriage returns \r

Control characters below U+0020 must all be escaped.

Symptom: usually an error partway through what looks like a normal string, or a mysterious "unexpected token" a few characters later.

Comments

{
  // the widget name
  "name": "widget"
}

JSON has no comment syntax. Neither // nor /* */ is valid.

Symptom: error at the first /.

This catches people constantly with config files, because config files are exactly where you want comments. JSON5 and JSONC allow them; standard parsers don't.

NaN, Infinity and undefined

{"value": NaN}
{"value": Infinity}
{"value": undefined}

None are valid JSON. The number grammar covers integers, decimals and exponents only. undefined isn't a JSON concept at all — use null.

Symptom: error at the start of the literal.

These usually arrive from a JavaScript serialisation that bypassed JSON.stringify, or from a division-by-zero that produced Infinity and was written out naively.

Leading zeros and malformed numbers

{"code": 007}
{"value": .5}
{"value": 1.}
{"value": +5}

All invalid. JSON numbers can't have leading zeros (except 0 itself), must have a digit before the decimal point, must have a digit after it, and can't have a leading +.

If you need 007 preserved as a string — a product code, a country code — quote it: "007".

Duplicate keys

{"id": 1, "id": 2}

Technically permitted by the JSON specification but with undefined behaviour. Most parsers keep the last occurrence; some keep the first; some throw.

Symptom: no error at all. This one is worse than a parse failure, because it fails silently and produces different results in different languages. It's also a known attack vector where two systems parse the same payload differently.

BOM at the start

A byte order mark before the opening brace makes the first character something other than {.

Symptom: "unexpected token" at position 0, on a file that looks perfectly fine.

Save as UTF-8 without BOM, or strip the BOM before parsing.

Truncated payload

{"users": [{"name": "Anna", "role":

The stream was cut off — a response size limit, a broken connection, a log line that got truncated.

Symptom: "unexpected end of JSON input."

Check the payload length against any Content-Length header, and check whether an intermediate proxy or logging system has a size cap.

Double-encoded JSON

"{\"name\": \"widget\"}"

The whole document is a string containing JSON, not JSON itself. Parses successfully and gives you a string.

Symptom: the parse succeeds but you can't access any fields. typeof result is "string".

Requires a second parse. The real fix is upstream — something serialised an already-serialised value.

A Diagnostic Sequence

When you hit an error:

1. Note the position and look backwards. Scan the 50 characters before it.

2. Check the obvious four first. Trailing comma, single quotes, unquoted key, comment. These account for most errors.

3. Format the document. Even a partial format shows you the structure up to the failure point, which usually makes the problem visible.

4. Check the boundaries. Is there a BOM at the start? Is the document complete at the end? Does the brace count balance?

5. If it parses but behaves oddly, check for double encoding and duplicate keys — the two failure modes that don't throw.

6. Bisect if the payload is large. Cut it in half, test each half. Three or four rounds isolates the problem in a very large document.

Preventing Rather Than Debugging

Always serialise with a library. Hand-built JSON via string concatenation is where escaping errors come from. JSON.stringify, json.dumps and their equivalents handle escaping correctly.

Validate at boundaries. Parse and validate incoming JSON at the edge of your system rather than deep inside it. The error is far easier to diagnose when you still have the raw payload.

Use a schema. JSON Schema catches structural problems a parser can't — a missing required field, a wrong type, a value out of range. A document can be perfectly valid JSON and completely wrong for your application.

Log the raw payload on parse failure. Logging only the error message throws away the one thing you need.

Consider JSON Lines for logs. One object per line means a truncated or malformed record affects one line rather than the entire file.

Be careful with numbers. JavaScript loses precision above 2^53. If you have large IDs, transmit them as strings.

Minify or Pretty Print

Two different jobs:

Pretty print for reading. Indentation, one key per line. Essential for anything you're inspecting by hand.

Minify for transmission. Removing whitespace reduces payload size meaningfully — often 10–20% on typical documents, before compression.

Gzip or Brotli compresses repeated whitespace efficiently, so the benefit of minification is smaller than it looks once compression is applied. It's still worth doing for high-volume APIs and not worth agonising over.

Never minify a config file that humans edit. The bytes saved aren't worth the readability cost.

FAQ

Why is a trailing comma invalid in JSON? The JSON grammar doesn't allow it. JavaScript and Python do, which is why the habit persists.

Can I use comments in JSON? Not in standard JSON. JSON5 and JSONC support them but require a parser that understands those variants.

What does "unexpected token" mean? The parser found a character that can't appear at that point in the grammar. Look just before the reported position for the actual cause.

Are duplicate keys an error? The specification permits them with undefined behaviour. Most parsers keep the last, but the inconsistency between implementations makes them worth avoiding.

Why does my JSON parse to a string? It's double-encoded — a JSON string containing JSON. Parse twice as a workaround, and fix the serialisation upstream.

Should I minify JSON? For API responses, yes, though compression captures most of the benefit. For human-edited config, no.

The Takeaway

JSON's strictness makes it predictable: there's a finite list of things that can go wrong, and four of them account for most failures. Reading the position marker backwards rather than forwards, and knowing that duplicate keys and double encoding fail silently rather than loudly, covers nearly everything you'll hit.

Validate, format and minify JSON free with the JSON Formatter at sadiqbd.com — no sign-up, instant results.

Ask AI about this article
Share: Facebook WhatsApp LinkedIn Email

JSON Formatter

Free, instant results — no sign-up required.

Open JSON Formatter →
Similar Tools
Regex Tester JWT Decoder Base64 Encoder/Decoder Timestamp Converter Bcrypt Generator Password Generator UUID Generator REST API Checker
Structured JSON Logging: How to Debug Production API Errors and Search Logs at Scale
Developer
Structured JSON Logging: How to Debug Production API Errors and Search Logs at Scale
Why 9007199254740993 Becomes 9007199254740992: JSON Numbers and JavaScript's Precision Limit
Developer
Why 9007199254740993 Becomes 9007199254740992: JSON Numbers and JavaScript's Precision Limit
Why JSON Doesn't Allow Comments — and the JSON5/JSONC Variants That Do (and Why They Break Standard Parsers)
Developer
Why JSON Doesn't Allow Comments — and the JSON5/JSONC Variants That Do (and Why They Break Standard Parsers)
Why JSON Parses Differently in JavaScript, Python, and Go — Precision, Duplicates, and Parser Security
Developer
Why JSON Parses Differently in JavaScript, Python, and Go — Precision, Duplicates, and Parser Security