10 Most Common JSON Errors and How to Fix Them (2026)
JSON is the most widely used data format on the web, but it is also unforgiving. One stray comma, one wrong quote character, and your entire API call fails. The parser gives you a position number that often points to the wrong line. Your app breaks in production. You lose an hour.
These are the ten JSON errors that developers search for and hit most often — ranked by how frequently they appear in Stack Overflow questions, GitHub issues, and support tickets. Each one comes with the exact error message you will see, a broken example, and the fix.
For any of these, you can paste your JSON directly into ToolPry's JSON Formatter and see the exact error highlighted in under a second.
In this article
#1 Trailing Comma
This is the single most common JSON error, and it happens to everyone. JavaScript allows trailing commas in object literals and arrays, so developers write them out of habit. JSON does not allow them — the specification is explicit.
The error message makes this particularly frustrating because it points to the closing brace or bracket, not the comma that caused the problem. Always check the line before where the parser complains.
BROKEN
{
"name": "Maria",
"role": "admin",
}
FIXED
{
"name": "Maria",
"role": "admin"
}
The same rule applies to arrays. ["a", "b", "c",] is invalid JSON. ["a", "b", "c"] is valid. Most code editors with JSON support (VS Code, Sublime) will highlight this immediately. If you use Prettier, it automatically removes trailing commas from JSON files on save.
#2 Missing Comma Between Properties
The opposite of error #1 — forgetting to add a comma between two properties. This often happens when you add a new property to an existing object or paste a block of JSON from another source.
BROKEN
{
"name": "Maria"
"role": "admin"
}
FIXED
{
"name": "Maria",
"role": "admin"
}
A good habit: when adding a new property at the end of an object, add the comma on the previous line before typing the new property. This avoids both this error and the trailing comma error simultaneously. The JSON Formatter will pinpoint the exact line where the comma is missing.
#3 Single Quotes Instead of Double Quotes
JavaScript accepts both single and double quotes for strings. JSON accepts only double quotes — for both keys and values. This trips up JavaScript developers constantly, and it is the most common error when copying JavaScript object literals into a JSON context.
BROKEN
{
'name': 'Maria',
'role': 'admin'
}
FIXED
{
"name": "Maria",
"role": "admin"
}
There is no shortcut — you must use double quotes everywhere. If you have a large block of JSON with single quotes (perhaps copied from a Python dictionary or a JavaScript object), a simple find-and-replace from ' to " will not always work safely because the string values themselves might contain apostrophes. Use a proper JSON formatter to handle this correctly.
#4 Unquoted Keys
In JavaScript object literals, keys do not need quotes if they are valid identifiers: {name: "Maria"} is valid JavaScript. It is not valid JSON. Every key in a JSON object must be a double-quoted string, no exceptions.
BROKEN
{
name: "Maria",
role: "admin"
}
FIXED
{
"name": "Maria",
"role": "admin"
}
This error comes up frequently when developers hand-write JSON configuration files. A good editor with JSON language mode enabled will flag unquoted keys with a red underline before you even try to parse the file. In VS Code, name your file with a .json extension and this validation is automatic.
#5 Unexpected Token < at Position 0
This is the most searched JSON error message on Stack Overflow, and it has nothing to do with your JSON syntax. When you see < at position 0, it means the server returned an HTML page instead of JSON. The < is the first character of <!DOCTYPE html> or an HTML error page.
Common causes: the API endpoint URL is wrong (you're hitting a 404 page), the server crashed and returned a 500 error page, authentication failed and the server redirected to a login page, or CORS is misconfigured and the browser received an HTML CORS error.
How to diagnose it
// Log the raw response before parsing const res = await fetch('/api/users'); const text = await res.text(); // read as text first console.log('Status:', res.status); console.log('Content-Type:', res.headers.get('content-type')); console.log('Body preview:', text.slice(0, 200)); // Only parse if it's actually JSON if (res.ok && res.headers.get('content-type')?.includes('application/json')) { const data = JSON.parse(text); }
The fix is almost never in your JSON — it is in fixing the API endpoint, the authentication headers, the server error, or the CORS configuration. Reading the raw response text first tells you exactly what the server actually sent back.
#6 Unexpected End of JSON Input
The parser reached the end of the string before the JSON structure was complete. This almost always means a missing closing brace }, bracket ], or quote ". It also happens when the response body is empty — you called JSON.parse("") or the server sent a 204 with no body and you tried to parse it.
BROKEN — unclosed object
{
"name": "Maria",
"items": [1, 2, 3]
← missing closing }
BROKEN — parsing an empty string
JSON.parse(""); // Unexpected end of JSON input
JSON.parse(undefined); // same error
JSON.parse(null); // same error
FIXED — guard against empty input
function safeParse(str) {
if (!str || !str.trim()) return null;
try {
return JSON.parse(str);
} catch (e) {
console.error('JSON parse failed:', e.message);
return null;
}
}
For mismatched brackets in large JSON files, paste into the JSON Formatter which visualises the nesting depth and immediately shows where the structure breaks.
#7 Comments in JSON
JSON does not support comments. Not // line comments, not /* block comments */. This surprises many developers because comments are so natural in configuration files, and JSON is so often used for configuration. Douglas Crockford, who designed JSON, explicitly removed comments from the spec to prevent it being used as a parsing directive channel.
BROKEN
{
// Database settings
"host": "localhost",
"port": 5432 /* default PostgreSQL port */
}
Workarounds
// Option 1: use a "_comment" key (harmless, widely understood) { "_comment": "Database settings", "host": "localhost", "port": 5432 } // Option 2: switch to JSONC or JSON5 for config files // VS Code settings.json, tsconfig.json use JSONC (JSON with Comments) // Option 3: strip comments before parsing with a library import { parse } from 'jsonc-parser'; // npm const config = parse(fileContents);
If you control the file format, switch to YAML or TOML for configuration files where you need comments. For API payloads and data interchange, stick to standard JSON and keep documentation in separate markdown files or a README.
#8 Unescaped Special Characters in Strings
Certain characters inside JSON strings must be escaped with a backslash. The characters that require escaping are: double quote \", backslash \\, forward slash \/ (optional but valid), and control characters including newline \n, tab \t, and carriage return \r.
The most common version of this error is an unescaped backslash — for example, a Windows file path like C:\Users\Maria\ embedded in a JSON string.
BROKEN
{
"path": "C:\Users\Maria\Documents",
"message": "She said "hello" to us"
}
FIXED
{
"path": "C:\\Users\\Maria\\Documents",
"message": "She said \"hello\" to us"
}
The safest approach is never to hand-craft JSON strings that contain special characters. Use your language's built-in serializer — JSON.stringify() in JavaScript, json.dumps() in Python, JsonSerializer.Serialize() in C# — and let it handle escaping automatically. These functions always produce valid JSON regardless of what characters are in your data.
#9 Invalid Values: undefined, NaN, Infinity, Functions, Dates
JSON supports exactly six data types: string, number, boolean, null, array, and object. Everything else is invalid. JavaScript developers frequently try to serialize values that have no JSON equivalent and are surprised by the result.
undefined is silently dropped by JSON.stringify() — the key disappears entirely. NaN and Infinity become null. Functions are silently dropped. Date objects are serialized as ISO 8601 strings, which is usually what you want, but they do not round-trip — parsing the string back gives you a string, not a Date object.
What happens to invalid values
JSON.stringify({ a: undefined }); // → "{}" (key removed!)
JSON.stringify({ a: NaN }); // → '{"a":null}'
JSON.stringify({ a: Infinity }); // → '{"a":null}'
JSON.stringify({ a: () => {} }); // → "{}" (function removed)
JSON.stringify({ a: new Date() }); // → '{"a":"2026-05-03T..."}'
FIXED — convert before serializing
const data = {
score: isFinite(score) ? score : null, // guard NaN/Infinity
value: value ?? null, // undefined → null
createdAt: date.toISOString(), // explicit string
callback: undefined // accept the drop, document it
};
The rule to remember: if a value cannot be represented as one of JSON's six types, you must convert it manually before serializing. Let the serializer handle escaping, but you handle type conversion.
#10 Circular Reference Error
This error occurs in JSON.stringify() — not in JSON.parse(). It means the object you are trying to serialize contains a reference back to itself, creating an infinite loop that the serializer detects and aborts.
Common causes: serializing DOM nodes (which reference their parent and children), Express.js response objects, objects with back-references in parent-child relationships, and Mongoose model instances that include connection references.
BROKEN
const a = {};
const b = { parent: a };
a.child = b; // a → b → a: circular!
JSON.stringify(a); // TypeError: Converting circular structure to JSON
FIXED — Option 1: use a replacer to skip circular refs
function stringifyCircular(obj) {
const seen = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]';
seen.add(value);
}
return value;
});
}
FIXED — Option 2: use flatted or json-stringify-safe
import { stringify } from 'flatted'; // npm install flatted
const safe = stringify(circularObj);
// or for simple cases, pick only the fields you need
const safe = JSON.stringify({
id: obj.id,
name: obj.name,
// do not include circular references
});
The cleanest fix is almost always the last one: only serialize the fields you actually need, not the entire object. This also produces smaller, more predictable JSON payloads — a good practice regardless of circular references.
Debugging Strategy That Works for Any JSON Error
When you hit an unfamiliar JSON error, follow this sequence. First, paste the raw JSON into ToolPry's JSON Formatter — it validates and highlights the exact error location. If the formatter says the JSON is valid but your code still fails, the problem is almost certainly how the JSON is being fetched or passed to the parser, not the JSON itself (see error #5 and #6 above).
Second, log the raw value before parsing. In JavaScript: const text = await res.text(); console.log(text.slice(0, 500));. This shows you exactly what the parser is receiving. You may discover it is an empty string, an HTML page, or a number rather than a string — all common surprises.
Third, always wrap JSON.parse() in a try/catch in production code. Unhandled JSON parse errors crash Node.js processes and break browser applications silently in some frameworks. Handling the exception lets you log the raw input for debugging and return a sensible fallback to the user.
Finally, validate JSON at the source. If you are building an API, add a JSON Schema validation step at your API boundary so malformed data is rejected with a clear error message before it propagates into your business logic. Tools like Ajv (JavaScript) and Pydantic (Python) make this straightforward.
Quick summary: Trailing comma (#1) and missing comma (#2) are the most common syntax errors. Unexpected token < (#5) means your server returned HTML — check your endpoint and auth headers. Circular reference (#10) is a serialization error, not a syntax error. For everything else, paste into the JSON Formatter first — it catches all of these instantly.