Skip to main content
CodeLint.Dev Dev Tools

JSON Formatter, Validator & Linter

Paste JSON that will not parse and find out exactly where and why, then format it cleanly. Everything runs in your browser — safe for tokens and customer data.

Input
Output

Output will appear here

Every JSON parse error, and what it actually means

Parser messages name a byte offset rather than the mistake. These are the errors you will actually hit, matched to their real cause.

Unexpected token } in JSON at position 42

Cause:A trailing comma before the closing brace. JavaScript object literals allow it; JSON does not. This is by a wide margin the most common JSON error.

Fix:Remove the comma after the final value: {"a": 1, "b": 2,} becomes {"a": 1, "b": 2}. The same applies to arrays.

Unexpected token ' in JSON at position 1

Cause:Single-quoted strings. JSON requires double quotes for both keys and string values — single quotes are not valid anywhere in the grammar.

Fix:Replace every ' with ". If the string contains an apostrophe, it needs no escaping inside double quotes.

Unexpected token o in JSON at position 1

Cause:You passed an object where a string was expected — the object was coerced to "[object Object]" and the parser choked on the second character. Usually JSON.parse() called on something already parsed.

Fix:Check whether the value is already an object. Many HTTP clients (axios, fetch with .json()) parse the body for you, so parsing again is a double-parse.

Unexpected token u in JSON at position 0

Cause:The value is the literal undefined. Almost always a variable that was never set, or a fetch whose body was already consumed.

Fix:A response body stream can only be read once. If you called .text() before .json(), the second read returns undefined.

Unexpected token < in JSON at position 0

Cause:The response is HTML, not JSON — typically an error page, a login redirect, or a proxy interstitial returned with a 200 status.

Fix:Log the raw response body before parsing. This is nearly always a 404 or 500 page, or an authentication redirect the client followed silently.

Unexpected non-whitespace character after JSON at position N

Cause:Two concatenated JSON documents, or JSON Lines (one object per line) being parsed as a single document.

Fix:For JSON Lines, split on newlines and parse each line separately. For a truncated-then-repeated payload, the source is usually a buffer being written twice.

Bad control character in string literal

Cause:A raw newline, tab or other character below U+0020 inside a string. JSON requires these to be escaped.

Fix:Escape them: a literal newline becomes \n, a tab \t. This commonly appears when a multi-line value is inserted without encoding.

Unexpected number in JSON at position N

Cause:A leading zero (007), a leading plus (+5), a trailing decimal point (5.), or a hex literal (0xFF). None are valid JSON numbers.

Fix:Write 7, 5, 5.0 and 255 respectively. NaN and Infinity are also invalid — they must be null or a string.

What RFC 8259 actually allows

JSON is defined by RFC 8259, which superseded RFC 7159 and the original RFC 4627. The grammar is deliberately tiny — small enough to parse with a deterministic state machine, which is why parsing stays fast at megabyte scale.

There are exactly six value types: object, array, string, number, boolean and null. That is the whole list. There is no date type, no binary type, no integer/float distinction, and no comment syntax.

The absences cause more trouble than the grammar does:

  • No comments. Not //, not /* */. If you need annotated config, use JSON5, JSONC or YAML — or add a "_comment" key, which is ugly but valid.
  • No trailing commas. The single most common cause of a parse failure.
  • No dates. Serialise as an ISO 8601 string. JSON.stringify(new Date()) does this for you; parsing back gives you a string, not a Date.
  • Numbers have no defined precision. The spec permits arbitrary precision but notes that implementations commonly use IEEE 754 doubles, which lose integer precision above 2⁵³.
  • Key order is not significant. Most parsers preserve insertion order in practice, but nothing in the spec requires it.

Encoding is fixed: RFC 8259 requires UTF-8 for JSON exchanged between systems, with no byte order mark. A BOM at the start of a file causes a parse error in most strict parsers, and it is invisible in every editor — worth checking if a file looks correct but will not parse.

Parsing safely in code

JavaScript — never parse unguarded
// JSON.parse throws. An unguarded call in a request handler
// takes down the request on any malformed input.
function safeParse(text) {
  try {
    return { ok: true, value: JSON.parse(text) };
  } catch (err) {
    return { ok: false, error: err.message };
  }
}

// Formatting: the third argument is the indent
JSON.stringify(value, null, 2);   // pretty, 2 spaces
JSON.stringify(value);            // minified
JavaScript — sorting keys for a clean diff
// Object key order is insignificant to JSON but very significant
// to a line-based diff. Sorting makes two configs comparable.
const sortKeys = (value) =>
  Array.isArray(value)
    ? value.map(sortKeys)
    : value && typeof value === 'object'
      ? Object.fromEntries(
          Object.keys(value).sort().map(k => [k, sortKeys(value[k])])
        )
      : value;

JSON.stringify(sortKeys(config), null, 2);
Python
import json

# Parse with a precise error location
try:
    data = json.loads(text)
except json.JSONDecodeError as e:
    print(f"{e.msg} at line {e.lineno} column {e.colno}")

# Format. sort_keys makes output diff-stable;
# ensure_ascii=False keeps non-Latin text readable.
json.dumps(data, indent=2, sort_keys=True, ensure_ascii=False)
Command line with jq
# Validate — exit code 0 if the document parses
jq empty file.json

# Format
jq . file.json

# Minify
jq -c . file.json

# Sort keys at every level
jq -S . file.json

JSON and its relatives

Several formats look like JSON and are not interchangeable with it.

FormatAddsWhere you meet it
JSON (RFC 8259)The baselineAPIs, config, data interchange
JSON5Comments, trailing commas, unquoted keys, single quotesHand-edited config files
JSONCComments and trailing commas onlyVS Code settings, tsconfig.json
JSON Lines (NDJSON)One complete JSON value per lineLog files, streaming exports, big-data pipelines
JSON SchemaA vocabulary for validating JSON structureAPI contracts, config validation
GeoJSON (RFC 7946)Geometry rules on top of JSONMapping. See the GeoJSON tools

A strict JSON parser rejects JSON5 and JSONC. tsconfig.json is JSONC, which is why copying it into a JSON.parse() call fails on the comments.

About

The JSON Formatter, Validator & Linter gives you four tools in one: Lint catches and describes every syntax error (trailing commas, unquoted keys, mismatched brackets); Format re-indents your JSON with consistent spacing; Pretty Print produces human-readable output with collapsible nodes; and Validate checks your document against the full JSON specification. A Sort Keys option lets you alphabetically sort all object keys at every nesting level — handy for diffing configs. Every operation runs entirely in your browser, so sensitive payloads from APIs, environment files, or internal services never leave your device. No sign-up, no rate limits, and no paywall.

How to use

  1. 1 Paste or type your JSON into the input panel on the left — error indicators appear immediately as you type.
  2. 2 Select a mode from the toolbar: Lint to see a list of errors, Format to re-indent cleanly, Pretty Print for a readable tree view, or Validate to confirm the document is spec-compliant.
  3. 3 Toggle Sort Keys in the options bar if you want object keys sorted alphabetically throughout the output.
  4. 4 Upload a JSON file by clicking the Upload button or dragging a .json file onto the editor.
  5. 5 Click the Share button to generate a shareable URL that encodes the current JSON, so you can send it to a colleague.
  6. 6 Use the Copy button to copy the formatted output to your clipboard, then paste it directly into your editor or API client.
How is this different from other JSON formatters like jsonformatter.curiousconcept.com?
Most formatters offer only pretty-printing. This tool combines four modes — Lint, Format, Pretty Print, and Validate — in a single interface. The Sort Keys option, shareable URL, and file upload are additional features not found together in most free tools. Everything runs client-side, which matters when your JSON contains API keys, PII, or internal service data.
What JSON errors does the linter catch?
The linter catches all JSON specification violations: trailing commas after the last element in an array or object, unquoted or single-quoted keys, missing commas between values, mismatched or unclosed brackets and braces, and invalid literal values (e.g. undefined or NaN, which are not valid JSON). Each error is reported with the exact line and column number.
What does Sort Keys do?
Sort Keys alphabetically sorts all object key names at every level of nesting in the JSON document. This is useful when comparing two JSON objects with a diff tool, because it ensures keys appear in a consistent order regardless of how the original data was produced.
Is my JSON data sent to a server?
No. All four modes — Lint, Format, Pretty Print, and Validate — run entirely in your browser using JavaScript. Your JSON data is never sent to any server, which makes it safe to paste API responses, authentication tokens, database exports, or any other sensitive payload.
Can I use this tool offline?
Yes. Once the page has loaded, the formatter works without an internet connection. This makes it reliable for air-gapped environments or when working on a flight.