Why JSON Validation Fails Silently and Where to Look First
JSON validation errors are rarely where you expect them. The parser reports the line where it gave up, not the line where you made the mistake. A missing comma on line 47 can surface as a parse error on line 52 because the parser continued attempting to recover through subsequent tokens before hitting a structural violation it could not rationalize away. Debugging the reported line without looking above it is the most common reason JSON debugging takes longer than it should.
The six syntax errors that account for the overwhelming majority of JSON parse failures, in order of how often they appear in practice:
- Trailing comma after the last element in an object or array:
{"name": "Alex", "role": "dev",}— the comma after"dev"is invalid strict JSON. This is valid in JavaScript object literals and JSON5, which is exactly why it appears so often — developers write JSON the same way they write JS objects. - Single quotes instead of double quotes:
{'name': 'Alex'}— JSON requires double quotes for every string and every property name, without exception. Single quotes are not an alternative. - Unquoted property names:
{name: "Alex"}— syntactically valid JavaScript, invalid JSON. Every key must be a quoted string. - Comments:
// this is a comment— JSON has no comment syntax at all. A forward slash at any structural position causes immediate parse failure. If your config format needs comments, you are using JSON5 or JSONC, not JSON. - JavaScript-only primitives:
{"score": NaN}or{"limit": Infinity}— the JSON specification supports onlynull. The valuesundefined,NaN,Infinity, and-Infinityare JavaScript primitives that do not exist in the JSON spec. - Unescaped control characters inside strings: raw tab characters, newlines, or null bytes inside a string value must be escaped as
\t,\n, or\u0000. Copying a multi-line string value directly from terminal output into JSON without escaping it will break the parse.
When a formatter reports a parse error at line N, scan lines N-5 through N for a missing comma, mismatched bracket, or unclosed string. The actual mistake is almost always above the reported line.
JSON vs JSON5 vs JSONC: Which Format Does Your Config File Actually Use?
Not every file with a .json extension is strict JSON. Several widely-used development tools write and consume extended JSON formats that deliberately add syntax the JSON specification prohibits. Pasting these files into a strict JSON validator and treating failures as bugs in your config is a diagnostic mistake.
JSON (RFC 8259) is the official specification. No comments. No trailing commas. No single quotes. No unquoted keys. No special numeric values beyond finite numbers. This is the format used by npm's package.json in its parsed form, most REST API response bodies, data interchange between services, and most databases that store or return JSON natively. If you are writing JSON that will be consumed by JSON.parse() anywhere in a pipeline, RFC 8259 is what you need to conform to.
JSON5 is a superset of JSON that adds single-line comments (//), multi-line block comments (/* */), trailing commas in both objects and arrays, unquoted keys when they are valid JavaScript identifiers, single-quoted strings, hexadecimal number literals, and the special values Infinity, -Infinity, and NaN. Babel's .babelrc config and certain ESLint and bundler configurations use JSON5. A JSON5 file parsed with a JSON5-aware parser works correctly. The same file fed to JSON.parse() or any strict JSON validator fails immediately — because it is not strict JSON, and that failure is expected behavior.
JSONC — JSON with Comments — is the narrowest extension: standard JSON syntax plus single-line and multi-line comments, and nothing else. VS Code's settings.json, tsconfig.json, and jsconfig.json are all JSONC. VS Code ships its own JSONC parser. When you paste a tsconfig.json with comments into a strict JSON formatter and it fails on the // line, your config is not broken — you are validating the wrong format against the wrong specification.
Before assuming your JSON is malformed, confirm which format the consuming parser actually expects.
Minified vs Pretty-Printed JSON: When Each Is the Right Choice
Minified and pretty-printed JSON are valid representations of identical data. The whitespace between them carries zero semantic meaning in the JSON specification — the choice between formats is entirely about the context in which the JSON is being produced or consumed.
Minified JSON belongs in production. Every byte eliminated from an API response payload reduces bandwidth cost and client-side latency. A 50KB pretty-printed JSON response minifies to approximately 35 to 38KB — roughly a 25% reduction from whitespace alone. At millions of API calls per day, that difference is measurable in infrastructure cost and in p95 response time. Storing JSON in databases or flat files where no human reads the raw data directly is the same calculation: smaller is faster and cheaper. Some legacy message queues and certain serialization contexts also interpret whitespace as meaningful, making minification a correctness requirement rather than just an optimization.
Pretty-printed JSON belongs wherever a human reads it. Debugging a 2,000-character single-line API response blob without formatting it first is not a workflow — it is a punishment. Configuration files that developers edit — package.json, .eslintrc, manifest.json — exist in pretty-printed form because they are maintained by people who need to read and modify them. Version control is the third compelling reason: a minified JSON file changed in a single property produces a diff that shows the entire file as modified, because the entire file is one line. A pretty-printed JSON file changed in one property produces a diff showing exactly the changed line, which is what code review is supposed to look like.
The workflow that handles both: develop and debug with pretty-printed JSON, deploy and transmit with minified. The Tooliest formatter converts in both directions from the same interface.
The Security Risk of Pasting API Responses Into Online JSON Formatters
Many developers paste API responses into online JSON formatters as a reflex — it is fast, it is familiar, and the formatted output makes debugging significantly easier. The problem is that API responses frequently contain content that should never leave your machine: bearer tokens, OAuth access tokens, session identifiers, API keys embedded in response metadata, and personally identifiable user data. Pasting any of these into a tool that transmits your input to a remote server is a data exposure event, regardless of how reputable the tool appears.
The exposure mechanism is specific. The tool's server receives your JSON payload as a request body and logs it — standard practice for virtually every web server for debugging, monitoring, and analytics purposes. Those server logs persist for days to months depending on the service's infrastructure and retention policy. Some online formatter tools have privacy policies that permit using submitted data for service improvement purposes, which means your API response may be retained and processed beyond the immediate request. OAuth access tokens and session tokens embedded in API responses have limited but non-zero expiration windows — a logged token is potentially usable by anyone with server log access until it expires. For tokens with multi-hour or multi-day validity windows, that is a meaningful exposure window.
For factual accuracy: JSONLint.com and JSONFormatter.org use server-side or cloud-function processing for their formatting operations. Most browser-extension JSON formatters that inject into page responses similarly route requests through remote infrastructure. The architecture is not always disclosed prominently.
The Tooliest JSON formatter processes your JSON entirely in your browser using JavaScript's native JSON.parse() and JSON.stringify(). No part of your JSON payload is transmitted to Tooliest servers at any point in the validation, formatting, or minification workflow. The parsing and formatting happen locally in your browser's JavaScript engine.
The practical rule is straightforward: for any JSON payload containing tokens, credentials, user data, or proprietary business logic — use a local tool, your browser's DevTools Network tab, or a confirmed browser-side formatter. For generic public API responses with no sensitive content, the risk is lower — but building the habit of using browser-side tools for all JSON work is simpler than performing per-request risk assessment before choosing a tool.
The same browser-side processing principle applies to Tooliest's PDF Splitter and Image Compressor — none of your files are uploaded to Tooliest servers.
JSON Data Types, Nesting Limits, and Large File Handling
JSON supports exactly six data types. Here is the quick reference:
- String:
"name": "Alex Chen"— must be double-quoted; Unicode is fully supported via\uXXXXescape sequences. - Number:
"score": 98.6— the JSON spec makes no distinction between integers and floating-point values; both are represented as the same number type.NaN,Infinity, and-Infinityare not valid JSON numbers. - Boolean:
"active": true— lowercase only.True,TRUE, and1are not valid JSON booleans. - Null:
"middle_name": null— lowercase only.Null,NULL, andundefinedare invalid. - Object:
"address": {"street": "Main St", "city": "Portland"}— unordered collection of key-value pairs where keys must be unique strings. - Array:
"tags": ["dev", "backend", "api"]— ordered list of any mix of the above types, including nested objects and other arrays.
The JSON specification imposes no formal nesting depth limit. In practice, browser JavaScript engines handle nesting up to 512 to 1,000 levels before stack overflow occurs, and Node.js and most server-side parsers are similarly bounded. If you are working with JSON that is legitimately 20 to 30 levels deep, that is almost always a schema design problem rather than a data representation requirement — the structure should be normalized, flattened, or moved to a database that handles relational data properly rather than encoded as recursive nesting.
For file size: the Tooliest JSON formatter handles files up to several MB in the browser without noticeable lag on modern hardware. Files above 5MB may introduce perceptible delay depending on available device RAM and the complexity of the nesting structure. For JSON datasets at 10MB or above, the right tool is not a browser-based formatter.
For JSON files too large for browser tools, jq is a free command-line processor — jq '.' file.json produces pretty-printed output instantly even on 100MB+ files, and its path expressions make it useful for extracting specific values without loading the full document into memory.
Frequently Asked Questions
Why does my JSON fail validation even though it looks correct?
The most common cause is a character that is visually identical to what JSON expects but is not. Smart quotes — Unicode curly quotes “ and ” — copied from a Slack message, Google Doc, or word processor look exactly like straight double quotes in most fonts but cause an immediate parse failure because JSON.parse() only recognizes ASCII " (U+0022). A non-breaking space (U+00A0) instead of a regular space in a property name produces the same invisible problem. The second most common cause is the error location mismatch described in Section 1 — the line the formatter flags is where parsing broke, not where the mistake was introduced. Paste your JSON into the Tooliest formatter and look at the error line, then scan three to ten lines above it for a missing comma, unclosed string, or mismatched bracket. A formatter that displays line numbers alongside the formatted output makes this significantly faster than reading raw unformatted text.
What is the difference between JSON.parse() and JSON.stringify() in JavaScript?
JSON.parse() takes a JSON string and deserializes it into a JavaScript value — an object, array, string, number, boolean, or null. JSON.stringify() takes a JavaScript value and serializes it to a JSON string. Both accept optional arguments that most developers underuse: JSON.stringify() takes a replacer as its second argument — either a function to transform values during serialization or an array of property names to include — and a space parameter as its third: JSON.stringify(obj, null, 2) produces the same 2-space indented output as a pretty-printer, which is useful when you need formatted JSON output directly in code rather than through a separate tool. JSON.parse() is strict and throws a SyntaxError on anything that is not valid RFC 8259 JSON — including JSON5 and JSONC. For parsing JSON5, the json5 npm package implements the correct superset parser.
How do I handle deeply nested JSON without losing track of structure?
A collapsible tree view is the right interface for navigating deeply nested JSON — most formatters including Tooliest's render an expandable tree view alongside the raw formatted output so you can collapse irrelevant branches and focus on the level you need. For programmatic access to deeply nested values in JavaScript, optional chaining (obj?.level1?.level2?.value) eliminates the TypeError cascade that breaks deep access on partially populated objects without requiring explicit null checks at every level. If you are consistently working with JSON that runs 10 or more levels deep, the correct intervention is usually at the schema level rather than the tooling level — normalize the data structure, move relational data to a database designed for it, or write a schema transformation that flattens the nesting before it reaches downstream consumers. For quickly extracting specific values from deeply nested production JSON without reformatting the entire document, jq's path expression syntax (jq '.level1.level2.level3' file.json) is faster and less error-prone than manually parsing the structure.
Can I validate JSON against a schema?
JSON Schema — currently through draft versions 04 to 2020-12 — is a separate specification that defines the structure, required properties, data types, value constraints, and relationships that a JSON document must conform to, independent of whether it is syntactically valid JSON. Validating against a JSON Schema requires a schema validator rather than a syntax formatter. For browser-based schema validation, jsonschemavalidator.net handles most draft versions without requiring local tooling. For programmatic validation in Node.js, ajv is the de facto standard — it is the most widely deployed JSON Schema validator in the JavaScript ecosystem and supports through draft 2020-12 with good performance on large documents. The Tooliest JSON formatter validates syntax — whether your document is valid JSON — but does not validate against a custom schema definition. For API contract testing and TypeScript type generation from JSON Schema definitions, quicktype generates type-safe interfaces across multiple target languages directly from your schema.
What causes 'Unexpected token' errors in JSON?
"Unexpected token" is JSON.parse()'s generic error for a character it cannot process in the current parser state. The most frequent triggers are a single quote where a double quote is expected, an unquoted property name where a string key is expected, a comment character at the start of a line, or a trailing comma immediately before a closing bracket or brace. In API response debugging, the specific error "Unexpected token < in JSON at position 0" means the server returned HTML instead of JSON — the response body starts with <html> or <!DOCTYPE rather than { or [. This almost always means the server returned an HTTP error page rather than a JSON error response, typically because the endpoint returned a 401, 403, 404, or 500 status and the error handling layer served an HTML error page to a client expecting JSON. The fix is on the server side or in the client's error handling, not in the JSON formatter.
How do I convert JSON to CSV?
Flat JSON arrays of objects — where every element is an object with the same property set — map cleanly to CSV: each object becomes a row, each property becomes a column header. Nested JSON does not map to CSV naturally because CSV is inherently flat, so nested structures either need to be flattened first or selectively extracted. For terminal-based conversion from a flat JSON array, the jq expression jq -r '(.[0] | keys_unsorted) as $keys | $keys, (.[] | [.[$keys[]]] | @csv)' file.json produces valid CSV output directly. For browser-based CSV work, papaparse is the standard JavaScript library for parsing and generating CSV and handles the JSON-to-CSV transformation with configurable flattening options. For the reverse direction — CSV to JSON — Tooliest has a dedicated converter that handles that transformation.
Is it safe to paste production API responses into an online formatter?
It depends entirely on what the response contains, but building a case-by-case judgment call into your workflow is a worse habit than just defaulting to browser-side tools. A public weather or currency API response with no authentication and no user data carries minimal risk. An API response containing a user's OAuth token, your application's API credentials, session data, or any personally identifiable information is a different situation entirely — that data ends up in server logs on infrastructure you do not control, retained for a duration you do not determine, under a privacy policy you may not have read. The Tooliest JSON formatter processes your JSON entirely in the browser using JSON.parse() and JSON.stringify() — zero bytes of your payload reach Tooliest servers. For production debugging that involves sensitive response data, the right tools in order of preference are your browser's DevTools Network tab, Postman with local processing configured, command-line jq, or a confirmed browser-side formatter. The habit worth building is using browser-side tools for all JSON formatting by default, rather than evaluating each request individually before choosing a tool.
Explore Related Categories
- Developer Tools - 6 tools
- JavaScript Tools - 4 tools
- HTML Tools - 5 tools