Debugging

10 JSON Syntax Errors That Waste Hours of Developer Time (And How to Fix Them)

10 min read

You paste a 400-line config file into your application. You hit run. The terminal spits back: SyntaxError: Unexpected token at position 2847. Position 2847. In a minified file. Now you are counting characters like an archaeologist brushing dust off a fossil.

This guide exists so you never have to do that again. These are the ten JSON syntax errors that waste the most developer time - and exactly how to fix each one.

1. Trailing Commas

This is the single most common JSON error. JavaScript allows trailing commas in objects and arrays. JSON does not. Not ever.

// WRONG - trailing comma after "editor" and after "true"
{
  "name": "Dana",
  "roles": ["admin", "editor",],
  "active": true,
}

// RIGHT - no trailing commas
{
  "name": "Dana",
  "roles": ["admin", "editor"],
  "active": true
}

This bites JavaScript developers constantly because every JS linter encourages trailing commas in code. Your muscle memory works against you. Some editors will even auto-add trailing commas in JSON files if you have the wrong formatter extension enabled. Watch for it.

2. Single Quotes Instead of Double Quotes

JSON requires double quotes for all strings and all keys. Single quotes, backticks, and unquoted strings are all invalid.

// WRONG - single quotes
{
  'name': 'Dana',
  'age': 30
}

// RIGHT - double quotes only
{
  "name": "Dana",
  "age": 30
}

Python developers hit this often because Python's dict representation uses single quotes by default. If you copy a Python dict from a REPL and try to use it as JSON, it will break. Use json.dumps() to get proper JSON output from Python.

3. Unquoted Keys

JavaScript object literals allow unquoted keys. JSON does not. Every key must be a double-quoted string, no exceptions.

// WRONG - unquoted keys
{
  name: "Dana",
  age: 30,
  isActive: true
}

// RIGHT - all keys double-quoted
{
  "name": "Dana",
  "age": 30,
  "isActive": true
}

This happens when people hand-write JSON or copy JavaScript object literals directly. Use JSON.stringify() to convert JavaScript objects to valid JSON rather than writing it by hand.

4. Missing or Mismatched Brackets

Every opening brace needs a closing brace. Every opening bracket needs a closing bracket. In deeply nested JSON, it is easy to lose track - especially when editing by hand.

// WRONG - missing closing bracket for "tags" array
{
  "name": "widget",
  "tags": ["ui", "component",
  "version": "2.0"
}

// RIGHT - bracket properly closed
{
  "name": "widget",
  "tags": ["ui", "component"],
  "version": "2.0"
}

A JSON formatter helps enormously here. Paste the broken JSON into a tool like jsonprettifier.com and the error highlighting will point you directly to the mismatched bracket. Counting brackets manually in a 500-line file is not a good use of your time.

5. Comments

JSON does not support comments. Not single-line with //, not multi-line with /* */, not in any form. This is one of the most frequently requested features and one of the most intentional omissions in the spec.

// WRONG - comments are not valid JSON
{
  // Database configuration
  "host": "localhost",
  "port": 5432, /* default PostgreSQL port */
  "name": "myapp"
}

// RIGHT - no comments
{
  "host": "localhost",
  "port": 5432,
  "name": "myapp"
}

If you need comments in configuration files, consider JSONC (JSON with Comments, supported by VS Code and TypeScript configs), JSON5, YAML, or TOML - all of which allow comments natively. For standard JSON, the common workaround is a documentation key:

{
  "_comment": "Database configuration",
  "host": "localhost",
  "port": 5432,
  "name": "myapp"
}

6. Using undefined

undefined is a JavaScript concept. It does not exist in JSON. When JavaScript's JSON.stringify() encounters undefined, it silently drops the key entirely - which can lead to confusing bugs where data just disappears.

// WRONG - undefined is not a JSON value
{
  "name": "Dana",
  "middleName": undefined,
  "age": 30
}

// RIGHT - use null for missing or empty values
{
  "name": "Dana",
  "middleName": null,
  "age": 30
}

Similarly, function, Symbol, and other JavaScript-specific types are not valid JSON values. If a value cannot be represented in JSON, use null or omit the key.

7. Top-Level Values

Technically, any JSON value type is valid as a top-level document according to RFC 8259. However, older parsers following RFC 4627 only accepted objects and arrays at the top level. This can cause subtle compatibility issues depending on which parser you are using.

// May fail in older parsers
"just a string"

42

true

// Universally safe - wrap in an object or array
{ "value": "just a string" }

[42]

{ "result": true }

In practice, wrapping top-level values in an object is a good habit. It makes the data self-describing and extensible - you can add more fields later without changing the structure.

8. NaN and Infinity

JSON numbers must be finite. NaN, Infinity, and -Infinityare not valid JSON values. JavaScript's JSON.stringify() converts them to null silently, which can mask bugs in your data pipeline.

// WRONG - these are not valid JSON numbers
{
  "result": NaN,
  "limit": Infinity,
  "threshold": -Infinity
}

// RIGHT - use null or a string representation
{
  "result": null,
  "limit": "Infinity",
  "threshold": "-Infinity"
}

// Or handle with a sentinel value
{
  "result": null,
  "resultError": "NaN - division by zero",
  "limit": 9999999999
}

If you need to represent these special numeric values in a data exchange, the common approach is using string representations or sentinel values, with clear documentation explaining the convention.

9. Duplicate Keys

The JSON spec says keys "SHOULD be unique" but does not strictly mandate it. Different parsers handle duplicate keys differently - most silently use the last value, some throw errors, and a few keep all duplicates. This inconsistency leads to subtle bugs and even security vulnerabilities.

// PROBLEMATIC - duplicate "status" key
{
  "id": 1,
  "status": "active",
  "name": "Widget",
  "status": "inactive"
}

// What does status equal? It depends on the parser.
// Most will say "inactive" (last wins), but don't rely on it.

// RIGHT - unique keys only
{
  "id": 1,
  "status": "inactive",
  "name": "Widget"
}

Duplicate keys usually happen through copy-paste errors or merge conflicts. A JSON validator will flag them. Some real-world security vulnerabilities have exploited parser differences in handling duplicates, so treating them as errors is the safest approach.

10. Encoding Issues

JSON must be encoded in UTF-8 (RFC 8259 made this mandatory). Problems arise when JSON is saved in other encodings or when special characters are not properly escaped.

// WRONG - literal control characters and unescaped backslashes
{
  "message": "Line 1
Line 2",
  "path": "C:\Users\test"
}

// RIGHT - escaped special characters
{
  "message": "Line 1\nLine 2",
  "path": "C:\\Users\\test"
}

Characters that must be escaped in JSON strings:

Windows file paths are a frequent offender because backslashes need to be doubled. If your JSON contains file paths and will not parse, check the backslashes first.

How to Prevent These Errors

Most of these errors share a root cause: writing JSON by hand. The more you can generate JSON programmatically, the fewer syntax errors you will encounter. Use JSON.stringify() in JavaScript, json.dumps() in Python, json.Marshal() in Go, or the equivalent function in your language. These functions produce valid JSON by construction.

For complex data structures, consider defining a JSON Schema to validate payloads automatically before they reach your application logic. Schema validation catches structural errors - missing fields, wrong types, values out of range - that syntactic validation alone cannot detect.

If you handle JSON in production systems, review our JSON security best practices to prevent injection attacks and data leaks. Security issues and syntax issues often overlap: improperly escaped strings can be both a parse error and a vulnerability.

When you do need to edit JSON manually - updating a config file, crafting a test fixture, debugging a payload - use a validator tool that highlights errors as you type. Catching a trailing comma in your editor is always better than discovering it in a production log at 2 AM.

Validate Your JSON Now

Paste a JSON file you are struggling with into our validator. It will highlight the exact line and character where your syntax breaks.

Open JSON Prettifier