Skip to content

JSON Repair Tool

Paste JSON that will not parse and get it back working, with every repair listed at the line and column it happened.

Everything on this page runs in your browser. Nothing is uploaded, logged or sent anywhere — your input is kept in the address bar so a link reopens it, which also means anything you paste travels with the link. Do not share a link to a payload you would not publish.

Repairs to applySwitch one off to see whether that class of problem is the one breaking your parser.
Output
Result
Valid after 13 repairs

The output below was passed through JSON.parse in your browser and came back clean. That check is what this claim rests on — not on the repair log.

The response was cut off. The value being written when the input ran out was $.note. Everything from there on is missing, not malformed — no repair recovers it. Raise the output token limit, or ask for the object in pieces.

Repaired JSON
{
  "vendor": "Acme B.V.",
  "amount_due": 1284.50,
  "currency": "EUR",
  "paid": false,
  "line_items": [
    {
      "sku": "A-1",
      "qty": 2,
      "unit_price": 12.5
    },
    {
      "sku": "A-2",
      "qty": 1,
      "unit_price": 9.99
    }
  ],
  "note": "Delivered to the loading bay"
}
Input characters
330
Output characters
302
Repairs applied
13
Of which must-fix
11
Object keys
12
Arrays
1
Deepest nesting
4
Ended mid-value
yes

Every repair, with the character it happened at

  1. checkMarkdown code fence around the JSONline 1, column 1

    The fence and the prose around it were dropped. Models add a fence back whenever the answer is long, so strip it in code rather than in the prompt.

    Sure! Here is the JSON you asked for:
    ^
  2. checkLine commentline 5, column 3

    JSON has no comments. Everything from `//` to the end of the line was dropped.

      // extracted from the scanned invoice
      ^
  3. must fixSingle-quoted stringline 6, column 3

    JSON strings are delimited by `"` and nothing else. Found `'`, which is valid JavaScript and invalid JSON.

      'vendor': "Acme B.V.",
      ^
  4. must fixUnquoted key `amount_due`line 7, column 3

    Object keys in JSON are strings, so they carry double quotes even when they look like identifiers. Quoted as `"amount_due"`.

      amount_due: 1284.50,
      ^
  5. must fixUnquoted key `currency`line 8, column 3

    Object keys in JSON are strings, so they carry double quotes even when they look like identifiers. Quoted as `"currency"`.

      currency: 'EUR',
      ^
  6. must fixSingle-quoted stringline 8, column 13

    JSON strings are delimited by `"` and nothing else. Found `'`, which is valid JavaScript and invalid JSON.

      currency: 'EUR',
                ^
  7. must fixUnquoted key `paid`line 9, column 3

    Object keys in JSON are strings, so they carry double quotes even when they look like identifiers. Quoted as `"paid"`.

      paid: False,
      ^
  8. must fixPython `False`line 9, column 9

    JSON booleans are lowercase. Rewritten as `false`.

      paid: False,
            ^
  9. must fixUnquoted key `line_items`line 10, column 3

    Object keys in JSON are strings, so they carry double quotes even when they look like identifiers. Quoted as `"line_items"`.

      line_items: [
      ^
  10. must fixTrailing comma before `}`line 11, column 48

    Legal in JavaScript and in JSON5, not in JSON. This is the single most common reason a hand-edited config file will not parse. Removed.

    …ku": "A-1", "qty": 2, "unit_price": 12.5,},
                                             ^
  11. must fixMissing comma between membersline 12, column 29

    Expected `,` or `}` after the value for "qty", found `"`. A comma was inserted.

        {"sku": "A-2", "qty": 1 "unit_price": 9.99}
                                ^
  12. must fixString never closedline 14, column 40

    The input ends inside a string. That is almost always a response cut off at the token limit rather than a syntax mistake — the closing quote was added at the end of the input, so the last value here is a fragment.

      "note": "Delivered to the loading bay
                                           ^
  13. must fixObject never closedline 14, column 40

    The input ends inside the object. A `}` was added.

      "note": "Delivered to the loading bay
                                           ^
What this assumes: numbers keep the digits you pasted rather than being run through a floating-point conversion, so a 19-digit ID comes out unchanged; a duplicate key resolves to the last one, which is what JSON.parse does but is not required by the spec; and a string that ends at a line break is closed there only when the next non-space character is one that cannot appear inside a continuing string (", ,, }, ] or the end of the input). Everywhere else the line break is escaped and the string continues.

What this actually does

It runs a tolerant JSON parser over your text — one that keeps going past a problem instead of stopping at it — and then re-serialises what it understood. Each departure from the JSON grammar is recorded with the byte it happened at, so the list above is the complete set of differences between what you pasted and what came out. Nothing is inferred beyond those repairs: no key is invented, no value is guessed, and a key whose value never arrived is dropped rather than filled with null.

The truncation case is different from the rest

Every other repair here is lossless — a single quote was always going to be a double quote, a trailing comma was always going to be nothing. Truncation is not. When a response stops mid-string, closing the brackets produces a document that parses, and that is worse than useless if you then treat it as complete: you get a half-written address, a price with its decimal point cut off, an array missing its last four items, and no exception anywhere. That is why this page names the path that was open when the input ran out and says so in plain words. If you are repairing truncated output in production, the repair is not the fix — the fix is a larger output budget, a smaller schema, or a length check before you trust the object.

What it does not check

Syntax only. It has no opinion on whether the result matches a schema, whether a field that should be a number is a string, or whether a date is in the format your database wants. It also does not detect encoding damage: text that arrived as mojibake parses perfectly and is still wrong. And it treats duplicate keys as recoverable when they are really a signal that two parts of your pipeline disagree about the shape of the object.

Why the repairs are toggles

Because "my JSON is broken" is usually one specific thing, and knowing which one tells you where to fix it upstream. Trailing commas mean a human edited the file. Single quotes and unquoted keys mean something printed a Python or JavaScript repr instead of serialising. None and False mean a Python dict was formatted with str() rather than json.dumps. A code fence means the model was asked for JSON in a chat format. An unclosed string means the token limit. Turn off the category you suspect, and if the document still fails, you have found it.

JSON Repair Tool · Multigrid