How to Validate JSON Before Deploying (The 5 Mistakes That Crash Apps)
JSON is forgiving to write and brutal to debug. The five validation mistakes that cause runtime crashes, the right tools to catch them, and a free browser-based validator and formatter.
JSON.parse() returns 'SyntaxError' for any malformed input, but most validation problems aren't malformed syntax — they're structural (missing fields, wrong types, unexpected nulls). To validate JSON before deploying, parse it, walk the structure, and check that every required field is present and the right type. For quick syntax checks, the Uttir JSON Validator catches the obvious cases in one click. For deep validation, use a schema (Zod, JSON Schema, Yup).
JSON is forgiving to write and brutal to debug. The syntax is simple, the parser is fast, and the first sign that something is wrong is often a runtime crash two hours after deploy. This guide covers the five validation mistakes that cause most of those crashes, the right way to catch them, and a free browser-based validator and formatter.
If you need to validate or format JSON right now, the Uttir JSON Validator and JSON Formatter run entirely in your browser, with line-and-column error reporting.
What "valid JSON" actually means
JSON has a strict spec. JSON.parse() in any browser will accept or reject based on that spec. The accepted cases are narrow:
- Objects:
{ "key": "value" }— double quotes only, keys must be strings, values must be valid JSON values. - Arrays:
[1, 2, 3]— values can be anything JSON allows. - Strings:
"hello"— double quotes only, no single quotes. - Numbers: integers or floats, no leading zeros, no NaN or Infinity.
- Booleans:
trueorfalse— lowercase only. - Null:
null— lowercase only.
Anything outside that is a syntax error. JSON.parse will throw a SyntaxError with a position. Most validators show that position as line and column, which is exactly what the Uttir JSON Validator does.
The five mistakes that crash apps
Mistake 1: Trailing commas
JavaScript allows trailing commas in objects and arrays. JSON does not. The most common cause of "this worked in dev but broke in prod" is a trailing comma that some bundler or template literal quietly added.
Wrong:
{ "name": "Ada", "age": 36, }
Right:
{ "name": "Ada", "age": 36 }
The JSON Formatter catches this on click — paste your JSON, click Format, and if there's a trailing comma, you'll see the line and column immediately.
Mistake 2: Single quotes
JSON requires double quotes for strings and keys. Single quotes are JavaScript, not JSON. A common source of this bug is copy-pasting from a JavaScript object literal that uses single quotes throughout.
Wrong:
{ 'name': 'Ada' }
Right:
{ "name": "Ada" }
Mistake 3: Unquoted keys
JavaScript allows unquoted keys for valid identifiers. JSON does not. Even if the key has no special characters, JSON requires double quotes around every key.
Wrong:
{ name: "Ada" }
Right:
{ "name": "Ada" }
Mistake 4: Comments
JSON does not support comments. // and /* */ are both syntax errors. JSON5 supports them, but standard JSON does not. If you need comments in a config file, use JSONC, JSON5, or YAML.
Mistake 5: NaN, Infinity, undefined
JSON does not have a representation for NaN, Infinity, or undefined. JavaScript's JSON.stringify silently turns them into null (or drops undefined entirely), but JSON.parse will never produce them. If you're constructing JSON by hand and you see NaN in your output, you have a bug.
For YAML — which does support these distinctions — convert with the JSON to YAML converter.
Beyond syntax: structural validation
Syntax validation catches malformed JSON. Structural validation catches JSON that parses but isn't what you expected. This is where most production bugs actually live — not in parse errors, but in fields that are missing, null, or the wrong type.
The 4-layer defense
- Schema — Zod, JSON Schema, Yup, or io-ts. Define the expected shape and types once.
- Type checking at the boundary — Validate API responses when they enter your app, before the rest of the code uses them.
- Default values — Where the schema makes a field optional, default to a safe empty value. Never trust that an optional field is present.
- Defensive reads — When the field could be null, undefined, or missing, handle all three.
user?.address?.city ?? 'Unknown'is much safer thanuser.address.city.
For a quick sanity check, the Uttir JSON Validator catches syntax errors. For full structural validation, use a schema library on the consumer side.
Validating API responses before deploy
Most production JSON bugs come from API responses that don't match the expected shape. The right place to catch this is at the boundary — when the response enters your code, not deep in the business logic.
Pattern with Zod (TypeScript):
import { z } from 'zod'; const UserSchema = z.object({ id: z.number().int().positive(), name: z.string().min(1), email: z.string().email(), role: z.enum(['admin', 'user']), createdAt: z.string().datetime(), }); const response = await fetch('/api/user/42').then(r => r.json()); const user = UserSchema.parse(response); // throws on mismatch
This catches missing fields, wrong types, and unexpected values in one place. The error is descriptive enough to debug immediately, and the rest of your code can trust that user matches the schema.
Validating JSON in CI
To prevent broken JSON from reaching production, add a validation step to your CI pipeline. For static config files, a one-line check works:
node -e "JSON.parse(require('fs').readFileSync('config.json'))"
For dynamic API contracts, generate JSON Schema from your backend (FastAPI, NestJS, and Express with zod-to-json-schema all do this), and validate responses against it in CI.
Common use cases on Uttir
The JSON Formatter and JSON Validator are useful in a few specific scenarios:
- Reading minified JSON — Paste a minified response from a curl command and format it for human reading.
- Finding the missing comma — When you have a parse error and need to know which line and column to look at.
- Converting to other formats — JSON to YAML for config files, CSV to JSON for spreadsheet data.
- Decoding JWTs — The header and payload are base64-encoded JSON. The JWT Decoder parses and pretty-prints both.
FAQ
Is there a difference between JSON.parse and JSON.stringify in validation?
They're inverses. JSON.parse(string) validates that a string is valid JSON and converts it to a JS value. JSON.stringify(value) takes a JS value and produces a JSON string. The stringifier never produces invalid JSON, but the parser is the validator — if JSON.parse doesn't throw, the input is valid.
Does JSON support comments?
Standard JSON does not. JSON5 (a popular extension) does, and so does JSONC (used by VS Code). YAML supports comments natively. If you need comments, use YAML or JSON5 — but note that strict JSON consumers (most APIs) will reject those formats.
What about big numbers?
JSON numbers are 64-bit floats. Integers above 2^53 lose precision. For IDs or values that exceed this (e.g. Twitter snowflake IDs, large database keys), pass them as strings to preserve them.
How do I validate JSON without running my code?
Use the Uttir JSON Validator for syntax checks. For structural validation without writing code, copy your JSON into a tool that supports JSON Schema (like jsonschemavalidator.net) and upload the schema alongside it.