How to Fix Invalid JSON -- A Developer's Debugging Guide

Last week, a production API started failing with SyntaxError: Unexpected token } in JSON at position 2847.

The payload was 3,000 lines long.

I spent two hours scanning through nested objects before realizing someone had added a trailing comma after the last property. One character. Two hours wasted.

If you've been there, you know the frustration. JSON errors are notoriously unhelpful. The parser tells you where it broke, but rarely why. And when you're dealing with API responses, configuration files, or data imports, finding that one misplaced character can feel like searching for a needle in a haystack.

This guide isn't about JSON syntax rules -- you can read those anywhere. Instead, I'll share the actual debugging workflow I use after years of wrestling with broken JSON in production systems. We'll cover:

  • The most common causes (and how to spot them quickly)
  • Real-world scenarios that catch developers off guard
  • A systematic debugging process that saves time
  • Tools that actually help (versus ones that waste your time)

Let's dive in.


Why JSON Is So Strict (And Why It Matters)

Before we jump into fixes, let's talk about why JSON breaks so easily.

JSON was designed for data interchange, not developer convenience. Unlike JavaScript object literals, which are forgiving and flexible, JSON has zero tolerance for syntax variations:

  • No trailing commas (even though JavaScript allows them)
  • No comments (yes, even // breaks it)
  • Double quotes only (single quotes are invalid)
  • No undefined values
  • Strict escaping rules for special characters

This strictness is intentional. It ensures that any valid JSON can be parsed consistently across every programming language and platform. Python, Java, Go, Rust -- they all parse JSON the same way.

But this consistency comes at a cost: tiny mistakes break everything. And the error messages? They're designed for machines, not humans.

When you see Unexpected token } at position 482, the parser isn't trying to be helpful. It's telling you exactly where it stopped reading. The rest is up to you.


The Most Common Causes (And How to Spot Them)

After debugging hundreds of JSON errors, I've noticed patterns. These five issues account for about 90% of all invalid JSON I encounter.

1. Trailing Commas -- The Silent Killer

This is hands-down the most common mistake, especially for JavaScript developers.

Here's the trap: JavaScript object literals allow trailing commas (since ES2017):

// This is perfectly valid JavaScript
const user = {
  name: "Alex",
  age: 30  // Trailing comma is fine here
};

But JSON? Not so much:

{
  "name": "Alex",
}

That trailing comma after "Alex"? It breaks everything.

Why this happens: Developers copy JavaScript objects into .json files, or manually edit large JSON payloads and accidentally leave a comma after removing the last property.

How to spot it: The error usually points to the closing brace } or bracket ]. If you see Unexpected token }, check the line before it for a trailing comma.


2. Single Quotes vs Double Quotes

Another classic. JavaScript is flexible with quotes:

const obj = { 'name': 'Alex' };  // Works fine

But JSON demands double quotes for both keys and string values:

{
  "name": "Alex"
}

Why this happens: Python developers often use single quotes by default. When serializing data or copying from Python code, they forget to convert to double quotes.

Quick fix: Use our JSON Formatter -- it automatically converts single quotes to double quotes and validates the result.


3. Missing Quotes Around Keys

JavaScript lets you omit quotes for object keys (if they're valid identifiers):

const obj = { name: "Alex" };  // Valid JS

JSON doesn't allow this shortcut:

{
  name: "Alex"  // ERROR: Keys must be quoted
}

The fix: Always wrap keys in double quotes:

{
  "name": "Alex"  // Correct
}

This trips up frontend developers who switch between JavaScript and JSON frequently.


4. Invalid Escape Characters

This one shows up constantly with Windows paths and regex patterns.

The problem: Backslashes are escape characters in JSON. So \n means "newline", \t means "tab", and \test is invalid.

Broken:

{
  "path": "C:\new_folder\test.txt"
}

The parser sees \n as a newline and \t as a tab, completely breaking the structure.

The fix: Escape backslashes properly:

{
  "path": "C:\\new_folder\\test.txt"
}

Or better yet, use forward slashes (they work on Windows too):

{
  "path": "C:/new_folder/test.txt"
}

When generating JSON programmatically, JSON.stringify() handles escaping automatically:

const path = "C:\\new_folder\\test.txt";
const json = JSON.stringify({ path });
// Result: {"path":"C:\\new_folder\\test.txt"}

5. Comments Inside JSON

Developers love comments. JSON does not.

Broken:

{
  // User configuration
  "theme": "dark"
}

Standard JSON has zero support for comments. None. Not even block comments.

Why? The JSON spec prioritizes simplicity and consistency. Comments add complexity without providing value for data interchange.

Alternatives if you need comments:

  • JSON5 -- A superset of JSON that allows comments
  • YAML -- Human-friendly format with comment support
  • TOML -- Great for configuration files
  • Separate documentation -- Keep comments in a README or schema file

Real-World Scenarios That Break JSON

Beyond syntax errors, there are situational problems that catch developers off guard.

APIs Returning HTML Instead of JSON

This is arguably the most frustrating scenario because the problem isn't in your JSON at all.

Your frontend expects JSON:

const data = await response.json();

But the server returns an HTML error page:

<!DOCTYPE html>
<html>
  <body>Login Required</body>
</html>

Suddenly you get:

SyntaxError: Unexpected token < in JSON at position 0

That < is the opening angle bracket of <!DOCTYPE html>.

Common causes:

  • Expired authentication (redirected to login page)
  • Wrong endpoint URL (404 error page)
  • Reverse proxy misconfiguration
  • Cloudflare bot protection pages
  • Server crashes returning error pages

How to debug: Check the raw response before parsing:

const response = await fetch('/api/data');
const text = await response.text();

console.log('Status:', response.status);
console.log('Content-Type:', response.headers.get('content-type'));
console.log('Response:', text.substring(0, 200));

// Now try to parse
try {
  const data = JSON.parse(text);
} catch (err) {
  console.error('Parse failed. Raw response:', text);
}

For a deep dive on this specific error, see How to Fix Unexpected Token in JSON.


AI-Generated JSON

With the rise of LLMs, this has become increasingly common.

AI models frequently generate JSON with:

  • Trailing commas
  • Markdown code block wrappers (triple backticks)
  • Inline comments
  • Incomplete brackets

Example from an AI response:

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

Looks correct visually. Still invalid JSON.

Best practice: Always validate AI-generated payloads before using them in production. Never trust LLM output blindly.


Broken package.json Files

One invalid comma in package.json can break your entire development workflow:

  • npm install fails
  • ESLint won't run
  • TypeScript compilation errors
  • Vite build crashes
  • Next.js dev server won't start

This usually happens during:

  • Manual dependency edits
  • Merge conflicts in git
  • Copy-pasting from documentation

Pro tip: Use npm pkg commands instead of editing package.json manually:

npm install lodash
npm uninstall old-package

My Actual Debugging Workflow

After dealing with malformed JSON too many times, I developed a systematic approach. This workflow saves me hours compared to manual scanning.

Step 1 -- Print the Raw Response

Never trust the parser error message alone. Start by inspecting what you're actually trying to parse:

const text = await response.text();
console.log('Raw response:', text);
console.log('Length:', text.length);
console.log('First 100 chars:', text.substring(0, 100));

This instantly reveals:

  • HTML responses (starts with <!)
  • Login redirects
  • Malformed payloads
  • Proxy errors

Nine times out of ten, you'll discover the issue has nothing to do with JSON syntax.


Step 2 -- Validate Externally

Paste the raw string into a validation tool. I use our JSON Validator because it:

  • Shows the exact line and column of the error
  • Highlights syntax issues visually
  • Explains what went wrong in plain English
  • Runs entirely in your browser (no data sent to servers)

For massive payloads (>10MB), use jq in the terminal:

cat large-file.json | jq .

jq is dramatically faster than browser tools for huge files.


Step 3 -- Check Content-Type Headers

Sometimes the payload is valid, but the server headers are wrong:

response.headers.get("content-type")
// Expected: "application/json"
// Got: "text/html"

If the server returns text/html, your parser error suddenly makes sense.


Step 4 -- Isolate the Problem

For large payloads, don't try to debug the entire structure at once:

  1. Remove nested sections incrementally
  2. Validate after each removal
  3. Narrow down to the problematic section
  4. Focus your debugging efforts there

This binary search approach is exponentially faster than line-by-line inspection.


Tools That Actually Help

Not all JSON tools are created equal. Here's what I actually use in production:

VSCode

Still the best general-purpose JSON inspector for medium-sized files.

Strengths:

  • Built-in formatting (Shift + Alt + F)
  • Syntax highlighting
  • Error squiggles
  • Quick fixes for common issues

Limitations:

  • Struggles with files >1MB
  • No tree view for complex structures

jq

The gold standard for CLI JSON processing.

Use it for:

  • Filtering large responses: cat data.json | jq '.users[] | select(.age > 30)'
  • Extracting specific fields: jq '.name' user.json
  • Validating syntax: jq . file.json
  • Transforming data: jq '{name, email}' users.json

Install: brew install jq (macOS) or apt-get install jq (Linux)

For huge payloads, jq is often 10-100x faster than browser tools.


Postman

Essential when debugging API-related JSON issues.

Why it helps:

  • Automatically formats JSON responses
  • Shows response headers (Content-Type, status codes)
  • Saves request history for comparison
  • Environment variables for testing different scenarios

The built-in JSON viewer is decent for everyday API debugging.


Online JSON Formatters

Perfect for quick validation and formatting copied payloads.

Critical consideration: Privacy.

Many online formatters upload your data to their servers. If you're working with:

  • Production API keys
  • User data
  • Proprietary configuration
  • Authentication tokens

...use tools that process JSON locally in the browser.

Try our JSON Formatter or JSON Validator -- both run entirely client-side. Your data never leaves your machine.


Common Mistakes Developers Make

Beyond syntax errors, these behavioral patterns cause unnecessary pain:

Confusing JavaScript Objects with JSON

This is probably the biggest source of confusion.

Valid JavaScript:

{
  name: 'Alex',
  age: undefined,
  active: true
}

Invalid JSON (for three reasons):

  • Unquoted keys
  • Single quotes
  • undefined is not a valid JSON value

Remember: JSON is a data format, not a programming language feature.


Manually Editing Large Payloads

Once a JSON file crosses a few hundred lines, manual editing becomes error-prone.

Better approach:

  1. Use a formatter with auto-fix capabilities
  2. Generate JSON programmatically when possible
  3. Use schema validation for critical files
  4. Implement pre-commit hooks to catch errors early

Ignoring Encoding Problems

Hidden BOM (Byte Order Mark) characters and invalid UTF-8 encoding can break parsing silently.

This especially happens when:

  • Exporting files from Excel or legacy systems
  • Copy-pasting from Word documents
  • Downloading files from Windows servers

Fix: Ensure files are saved as UTF-8 without BOM. Most modern editors show encoding in the status bar.


Trusting API Responses Blindly

Never assume APIs always return valid JSON.

Always:

  1. Check HTTP status codes
  2. Verify Content-Type headers
  3. Inspect raw responses during debugging
  4. Add error handling for parse failures

Defensive coding saves hours of debugging later.


FAQ

Why is my JSON invalid?

The most common reasons are:

  • Trailing commas after the last element
  • Single quotes instead of double quotes
  • Missing quotes around keys
  • Invalid escape sequences (especially in Windows paths)
  • Comments inside JSON

Use a validator to pinpoint the exact issue.


Why does JSON.parse fail?

Because JSON syntax is intentionally strict. Even one invalid character breaks parsing completely. The parser doesn't attempt "best guess" interpretation -- it either succeeds or fails.


Can JSON contain comments?

No. Standard JSON does not support comments of any kind. If you need comments, use JSON5, YAML, or TOML instead. Or keep documentation separate from the data.


Are JavaScript objects valid JSON?

Not always. JavaScript object literals are more permissive:

  • They allow trailing commas
  • They support single quotes
  • Keys can be unquoted (if valid identifiers)
  • Values can be undefined, functions, or Symbols

JSON is stricter. Always validate when converting between the two.


What's the fastest way to validate JSON?

For quick checks:

For large files (>10MB):

  • jq -- Command-line tool, extremely fast
  • Streaming parsers -- Process in chunks to avoid memory issues

Automated validation is always faster than manual inspection.


Should I validate JSON on the client or server?

Both. Validate on the server for security (never trust client input). Validate on the client for better user experience (catch errors before sending to server).


Final Thoughts

JSON errors are inevitable. You'll encounter them whether you're working with APIs, configuration files, or data imports.

The key isn't avoiding them entirely -- it's developing a systematic approach to debugging them quickly.

My advice:

  1. Stop writing JSON by hand. Use JSON.stringify() or generators.
  2. Validate early and often. Don't wait for production to catch errors.
  3. Use the right tools. A good formatter saves hours of manual scanning.
  4. Add defensive code. Wrap JSON.parse() in try-catch blocks.
  5. Check raw responses. The error is rarely where you think it is.

Most importantly: when you hit that dreaded Unexpected token error, don't panic. Print the raw response, validate externally, and trace back to the source.

Your future self will thank you.


Struggling with invalid JSON right now? Try our JSON Validator -- paste your JSON, get instant feedback with exact error locations, and fix issues in seconds. All processing happens in your browser, so your data stays private.

Or use the JSON Formatter to beautify, minify, and validate in one step. Both tools run entirely client-side -- no data ever leaves your machine.