Tools · NDJSON

JSONL validator

Every line is parsed on its own. The verdict counts the records and the lines that will not parse, each broken line is named with its fix, and Fix all rewrites those lines alone.

no signup · runs entirely in your browser · ⌘V works anywhere on this page
See it done · 8 s
Validate JSON LinesFive records, one that will not parse: the verdict counts it, the row names it, and Fix all rewrites that line alone. · 8 s

What you get

  • Reads the sample as 5 records with 1 that will not parse — and names that line with its fix
  • Names the four things an upload refuses, each on its line — the fine-tuning sample's a byte-order mark before line 1, extra comma at the end, one record written across 6 lines, single quotes → double — and fixes all 4
  • Reads a whole file that is one JSON array as what it is, and writes one record per line instead
  • Fixes the named lines in one click and leaves every other byte as pasted; ⌘Z in the app puts the original back
  • Shows the records as a table with level chips, a filter and a panel per record in the app
  • Converts the validated lines to a JSON array or CSV from the sibling pages

What it will not do

  • Check a schema. It says whether each line is JSON, not whether the JSON has the fields a service wants.
  • Repair a line without saying what changed. Every fix has a name and a line number.
  • Send your text anywhere. The page is static and the engine runs in this tab — open the network panel and watch it stay empty.

What a line can be

A record

One complete JSON value on one line — the only thing a valid line is.

A trailing comma
{"a": 1,}{"a": 1}

Named on its line and fixed there; the other lines are untouched.

A record pretty-printed across lines
{ "a": 1 }{"a": 1}

The most common upload failure: one value over several lines is named as one record and joined onto one line — the lines between were never separate records.

A byte-order mark

An invisible first character a spreadsheet or an editor adds; it makes line 1 fail. Named as what it is, and stripped.

A JSON array, not lines
[{"a": 1}, {"a": 2}]{"a":1} {"a":2}

A .json file renamed .jsonl: one value, not one per line. Named, and written one record per line.

A blank line

Skipped, not counted as broken.

The sample

What the first sample opens — a real file, not an illustration written for this page.

checkout-api.ndjson
{"ts":"2026-04-21T14:32:08.412Z","level":"info","msg":"stripe.charge.completed","amount":17054,"order_id":"ord_8f3aa19c4d"}
{"ts":"2026-04-21T14:32:07.940Z","level":"warn","msg":"retry.scheduled","attempt":2,"backoff_ms":400}
{"ts":"2026-04-21T14:32:07.813Z","level":"error","msg":"stripe.webhook.signature_invalid","payload":"{\"event\":\"charge.succeeded\",\"id\":\"evt_1PZ3xK\"}"}
{"ts":"2026-04-21T14:32:07.512Z","level":"info","msg":"cart.items.priced","items":2,"total":14900
{"ts":"2026-04-21T14:32:06.301Z","level":"info","msg":"session.token.issued","ttl":3600}

in VS Code

Diagnostics on JSON Lines mark each broken record; the status bar counts them, and each fix is on the lightbulb of its line.

unstringify for VS Code14-day trial · Free and Pro

Questions

Why does an upload say the file is invalid JSONL?

Almost always one of four things: a value pretty-printed over several lines, a trailing comma, a byte-order mark at the start, or a .json file that is one array rather than one object per line. The page names which line, and the fix.

Is a blank line an error?

No. Blank lines are skipped. A line with only whitespace is skipped too.

Does it check the fields a fine-tuning file needs?

No. It checks that every line is JSON and fixes the ones that are not; the field rules belong to the service you upload to.

Try it on the file that broke your afternoon.

free while in alpha · no signup