The error message says Unexpected token or JSON.parse: unexpected character or Expecting ',' delimiter. You know the payload is the problem. You do not know where.
This is one of the most common stalls in web work. The UI is blank. The webhook never fires the right branch. A script that ran yesterday dies today. Somewhere in a pile of braces, one character is wrong, and the rest of the document might be fine.
You do not need a theory of parsers. You need a way to find the first real error, fix it, and confirm the document is valid JSON. A JSON formatter that also validates is built for that. Nicxro’s tool will not just pretty-print success. It should refuse broken input and point you at the break.
This guide is about reading those errors, fixing the usual causes, and stopping the loop where you “fix” the wrong thing three times.
Valid JSON and “looks like JSON” are not the same
A lot of text looks like JSON. JavaScript object literals look like JSON. Python dicts look like JSON. Log lines that wrap an object in extra text look like JSON. YAML with braces can fool you from across the room.
JSON is a strict format. Double quotes on keys. Double quotes on strings. No comments. No trailing commas. No undefined. true and false in lowercase. null in lowercase. Numbers without leading zeros, except 0 itself. No functions. No NaN. No Infinity.
If you paste something that is almost JSON, a validator should fail. That is the point. Tools that try to be helpful by auto-fixing quotes can hide the fact that your producer is emitting the wrong format. You want to know that.
When an app breaks, ask a blunt question: is this JSON, or is this a cousin? If it is a cousin, formatting it as JSON will never work until you convert it.
Why the error is often “at position 0”
Position 0 errors feel insulting. The parser did not even start.
Common reasons:
The payload is empty. JSON.parse("") fails immediately.
The payload is HTML. You requested JSON and got a login page, a 404 page, or an nginx error. The first character is <. The parser expected { or [.
The payload has a BOM or invisible character at the start. Copy-paste from Word, Slack, or a PDF can introduce this. The document looks perfect. The first code point is not {.
The payload is wrapped. Some servers send )]}',\n{"ok":true} as a JSON hijacking prefix. Some logs print INFO response= before the object. The JSON is in there. The string you parsed is not only JSON.
When the formatter fails at the beginning, do not hunt for a missing comma on line 80. Look at the first twenty characters in a raw view. If you see <!DOCTYPE, you are debugging the wrong layer. Fix the request, the auth, or the URL.
How to use a validator without guessing
Paste the full payload into Nicxro’s JSON formatter. Do not paste a slice unless you are sure the slice is a complete value. A fragment like "email": "a@b.com" is not JSON. An object or array is.
Run format or validate. If it succeeds, your syntax is fine. The bug is in meaning, not grammar. The field might be the wrong type. A key might be missing. That is a different article. Stop treating it as a parse error.
If it fails, use the line and column if the tool gives them. Open the formatted attempt, or look at the raw text around that point. The actual mistake is often one token before the reported position. Parsers notice the problem when they hit the next unexpected character.
Fix one issue. Validate again. Do not rewrite the whole file. JSON errors stack. The second error may be imaginary until the first one is gone.
If the document is huge, isolate. Copy the smallest complete object that should stand alone. Validate that. Then validate the parent. This is how you find a bad element in a large array without drowning.
The errors you will see over and over
Trailing commas
{ "a": 1, } is invalid. So is [1, 2, ]. JavaScript allows this. TypeScript compiled to JS allows this. JSON does not.
If you generated the file from a JS object and then hand-edited it, you probably left a comma after the last property. Remove it.
Single quotes
{ 'name': 'Sam' } is not JSON. Replace singles with doubles. If a string contains a double quote, escape it as \".
Unquoted keys
{ name: "Sam" } is JavaScript. JSON needs { "name": "Sam" }.
Comments
{ "debug": true /* prod */ } will fail. Strip comments, or stop calling the file JSON.
Wrong literals
True, False, None, nil, NULL, undefined all fail. JSON wants true, false, null.
This shows up when someone prints a Python dict and hopes. json.dumps exists for a reason.
Extra data after the value
{"ok": true}{"ok": true} is two documents. Standard JSON.parse wants one value. NDJSON, JSON Lines, and concatenated blobs need a different reader. If you have a stream of objects, split on newlines first, then validate each line.
Truncated payloads
A connection dropped. A log line hit a size limit. You copied from a UI that ellipsized the middle. The formatter will fail near the end with an unexpected end of input. The fix is to get the complete body, not to close braces by hand unless you know what was cut.
Bad escapes
\x is not a JSON escape. Valid ones include \", \\, \/, \b, \f, \n, \r, \t, and \uXXXX. Windows paths pasted into JSON are a frequent mess: C:\new\test contains \n and \t. Use C:\\new\\test or forward slashes.
Numbers that are not numbers
01 is invalid. 1. is invalid in strict JSON. 1e is invalid. NaN is invalid. If you need those values, you are not in JSON anymore.
Syntax can be valid and the app can still break
Once the formatter succeeds, you have well-formed JSON. You do not have correct JSON.
A field named userId in the API and user_id in your client is valid on both sides and still empty in the UI. A number arrives as "42" and your math silently concatenates. An array arrives as an object. null arrives where you expected [].
Validation does not replace a schema. If you have one, use it. If you do not, formatted JSON is still the fastest way to compare expected keys with actual keys.
Write down the keys you require. Then look at the formatted document. Missing keys are easier to see when each one has its own line.
How production JSON gets corrupted
Proxies rewrite bodies. Content-encoding gets double-applied. A middleware logs the body and accidentally truncates it. A client sends Content-Type: application/json with a form body. A server returns JSON with a PHP warning printed before the {.
When a validator fails on a production capture, save the raw bytes if you can. Look at headers. Content-Type lying is common. So is gzip being decoded twice, which turns JSON into binary junk that looks like chaos in a text box.
If the capture includes a stack trace mixed into the body, you are not holding JSON. You are holding an error page. Fix the exception. The parse error is a symptom.
A working debug loop
- Get the raw body. Not a pretty console summary. The actual string.
- Paste it into the Nicxro JSON formatter.
- If it fails at the start, inspect the first characters for HTML, prefixes, or blanks.
- If it fails in the middle, fix the reported token, usually a comma, quote, or literal.
- If it succeeds, compare shape: types, nulls, missing keys.
- Only then change application code.
Skipping to step 6 is how people “fix” JSON by adding try/catch and swallowing the error. The UI stays empty. The log says parse failed. Nothing gets better.
What to do with errors you cannot paste
Some payloads include customer data. Do not drop them into a random public box if the tool sends data to a server you do not trust. Prefer a formatter that runs in the browser. Nicxro is a tools site for this kind of local, practical work. Still, redact tokens and emails when you can.
If the payload is too large for a text area, validate a slice that is a complete value, or run a local check. The method stays the same. Parse. Read the first error. Fix that error. Repeat.
Teach the producer, not only the parser
If you keep fixing the same trailing comma, the generator is wrong. If logs keep wrapping JSON in extra text, the logger is wrong. If a partner sends single quotes, send them a tiny spec: RFC 8259, double quotes, UTF-8, one value per body.
A validator is a flashlight. It should not become the product. Use it to make the real source emit clean JSON.
When the Nicxro formatter accepts the payload, you have a baseline. From there you can talk about business rules. Until it accepts the payload, you are still arguing about commas. That argument is worth winning quickly, then leaving behind.