Back to blog

JSON Validation: Common Mistakes and How to Fix Them

JSON looks simple — until a trailing comma breaks your API. Here are the ten most common JSON errors, with explanations and fixes.

Published August 1, 2026· by TextOpal Team· 6 min read
jsonapideveloper-tools

JSON is one of the most popular data formats on the web. It's simple, human-readable, and supported by every modern language. But "simple" doesn't mean "foolproof" — and the moment you start passing JSON between systems, you'll discover the ten ways it can break.

Here are the most common JSON validation errors, why they happen, and how to fix them.

1. Trailing commas

{
  "name": "John",
  "age": 30,
}

The trailing comma after 30 is invalid JSON. JavaScript objects allow it (and many linters normalize it), but the JSON spec is strict. Remove the comma.

Why it happens: Developers copy from JavaScript and forget to strip the trailing comma. Many IDEs add it automatically in JS files.

2. Single quotes

{
  'name': 'John',
  'age': 30
}

JSON requires double quotes for strings, keys, and values. Single quotes are invalid. This is the most common error when copy-pasting from JavaScript object literals.

Why it happens: JavaScript objects can use either quote style. JSON strictly requires double quotes.

3. Unquoted keys

{
  name: "John",
  age: 30
}

Keys must be in double quotes. name and age without quotes are valid JavaScript object syntax, but invalid JSON.

Why it happens: JavaScript shorthand syntax is common, and developers forget that JSON is stricter.

4. Comments

{
  // This is a user
  "name": "John",
  "age": 30 /* age in years */
}

JSON does not support comments. Neither // line comments nor /* */ block comments are allowed. If you need comments in your config files, use JSON5, JSONC, or YAML — but be aware that standard JSON parsers will reject them.

Why it happens: JSONC (used by VS Code) and JSON5 are popular variants that allow comments. Developers forget that these aren't standard JSON.

5. Numbers as strings or vice versa

{
  "id": "12345",  // string instead of number
  "quantity": "10",  // string instead of number
  "price": 19.99  // number is correct
}

JSON distinguishes numbers from strings. A number like 12345 is 12345 — no quotes. A string like "12345" is text. APIs that expect a number will reject a string, even if the string contains digits.

Why it happens: Databases often store IDs as strings (to avoid integer overflow). When exporting to JSON, the string is preserved. The receiving API may expect a number.

6. Booleans and null

{
  "active": "true",  // string instead of boolean
  "deleted": "false",  // string instead of boolean
  "parent_id": "null"  // string instead of null
}

JSON has native true, false, and null values. They are not strings. "true" is a 4-character string; true is a boolean. APIs that expect a boolean will reject the string.

Why it happens: When data is read from a form or URL parameter, it comes in as a string. If the conversion to a boolean isn't done before serialization, you get strings.

7. NaN and Infinity

{
  "value": NaN,
  "limit": Infinity
}

JSON does not support NaN or Infinity. These are JavaScript-specific values that have no JSON representation. The standard JSON.stringify() converts them to null, which is rarely what you want.

Why it happens: Floating-point math can produce NaN or Infinity. If you serialize without checking, you get silent data loss.

Fix: Check for these values before serialization and either omit the field, replace with null, or throw an error.

8. Circular references

const obj = { name: "John" };
obj.self = obj;
JSON.stringify(obj);
// → TypeError: Converting circular structure to JSON

JSON is a tree structure, not a graph. Circular references cannot be represented. The standard JSON.stringify throws a TypeError; many serializers silently fail or produce invalid output.

Why it happens: DOM elements, React components, and class instances often have circular references. Serializing them directly without extracting the relevant data fails.

Fix: Extract the fields you need into a plain object before serializing. For graphs, use a reference system (like {"$ref": "#/path/to/object"}) and a library that resolves them.

9. Mixed character encoding

{
  "name": "José"
}

This looks fine, but if the file is saved as Latin-1 and parsed as UTF-8 (or vice versa), the é becomes é or similar mojibake. JSON spec requires UTF-8, but many systems use other encodings by default.

Why it happens: Windows editors default to Latin-1 or CP-1252. Mac editors default to UTF-8. When files are transferred between systems, encoding can be misinterpreted.

Fix: Save all JSON files as UTF-8 without BOM. Specify the encoding explicitly when reading and writing.

10. Incorrect escaping

{
  "path": "C:\Users\John",
  "regex": "\d+"
}

JSON strings use backslash as an escape character. \U, \d, and most other backslash sequences are invalid. Valid JSON escape sequences are: \", \\, \/, \b, \f, \n, \r, \t, and \uXXXX (where XXXX is a 4-digit hex).

Why it happens: Windows paths and regex patterns use backslashes liberally. Pasting them into JSON without escaping breaks the file.

Fix: Double every backslash: "C:\\Users\\John", "\\d+". Or use forward slashes for paths ("C:/Users/John") which work on Windows too.

Validating JSON

When you're debugging a JSON error, the error message you get from JSON.parse is often unhelpful: "Unexpected token at position N" doesn't tell you what's wrong, only where. And on newer V8 engines, the more detailed "at line X, col Y" hint was removed.

A good JSON validator does two things:

  1. Pinpoints the error location with line and column.
  2. Shows the offending character so you can see what's wrong.

TextOpal's JSON Formatter includes a custom tokenizer that locates errors precisely, even when the native parser's error message is vague. Drop in a malformed JSON file, and you'll see the exact character that's breaking, with a caret beneath it.

Pretty-printing and minification

Beyond validation, two common operations on JSON are pretty-printing (for human readability) and minification (for transmission size).

Pretty-print: Use JSON.stringify(value, null, 2) for 2-space indentation, or JSON.stringify(value, null, 4) for 4-space. The 2-space style is more compact; 4-space is more readable.

Minify: Use JSON.stringify(value) with no indentation argument. This produces the smallest valid JSON.

When you're working with large JSON files (megabytes), pretty-printing them in a text editor can slow down or crash the editor. A dedicated JSON formatter that streams the input and outputs the formatted version is more robust.

Schema validation

JSON Schema is a separate spec that defines the expected structure of a JSON document — required fields, types, value ranges, etc. It's useful for validating API requests and configuration files.

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name"]
}

Libraries like Ajv (JavaScript), jsonschema (Python), and gojsonschema (Go) validate JSON against schemas. Use them in API handlers to reject invalid input early, before it reaches your business logic.

The bottom line

JSON is simple, but the strictness of its spec is what causes most errors. The most common mistakes — trailing commas, single quotes, unquoted keys, comments — are all artifacts of developers treating JSON as if it were JavaScript. They're not the same language.

A good JSON validator catches these errors at development time, before they reach production. Run every JSON file through one before committing, and configure your editor to lint JSON files automatically. The five seconds you spend validating now saves the hour you'd spend debugging a malformed API request later.

Try the tool

JSON Formatter and Validator

Related articles

TextOpal home