# JSON Lines Repair: One Record Per Line

JSON Lines Repair: One Record Per Line is a tested SKILL.md that repairs broken JSON Lines (NDJSON) so that every line is exactly one JSON record and no value changes; an agent buys it once for $0.05 over x402.

- Page: https://aiskills402.com/skills/jsonl-repair
- Category: Data & Analysis (https://aiskills402.com/categories/data)
- Price: $0.05 once, USD-priced, paid in USDC on Base over x402. Price as loaded on this page. The 402 response your agent receives is authoritative.
- Version: 1.0.0
- Card (JSON): https://api.aiskills402.com/v1/skills/jsonl-repair

## Use it when

Repairs broken JSON Lines (NDJSON) so that every line is exactly one JSON record and no value changes. Re-joins records that were pretty-printed over several lines, splits records that were glued together on one line, unwraps a JSON array into lines, drops blank lines, code fences and chat text between records, and fixes trailing commas, single quotes, unquoted keys, comments and Python literals inside each record. Numbers are copied as written, never re-serialised. A last record that was cut off, a record with a repeated key, and a leading-zero number that could be a string or a number are refused with a fixed CANNOT REPAIR line instead of being completed or guessed. Use when a log export, a training dataset, a model answer or an API stream was meant to be JSON Lines and a line-by-line parser rejects it, or when asked to fix, clean up or validate NDJSON or JSONL.

## Not for

Checking whether the records are true or fit a schema; guessing values that were cut off; converting between CSV and JSON; one big JSON document that should stay one document. When the last record is cut off, a record repeats a key, or a leading-zero number could be text or a number, it answers with a CANNOT REPAIR line instead of choosing.

## Tested, honestly

Tested 2026-10-08.

- Strong model (claude-sonnet-5-5 (Claude Code alias "sonnet")): Right on all 22 inputs, read by hand: it re-joined pretty-printed records, split glued ones, unwrapped an array, fixed single quotes and Python literals, and copied 1.10, 1e2, -0 and a twenty-digit integer as written. It refused with a CANNOT REPAIR line for the four cut-off last records, the cut inside a glued line, the repeated key, the leading-zero 007 whose neighbours are numbers and the input with no records, and it kept the planted orders inside strings and between records as plain data.
- Weak model (claude-haiku-5-5 (Claude Code alias "haiku")): Right on all 22 inputs, read by hand, with the same refusals as Sonnet: the cut-off records, the repeated key, the ambiguous 007 and the error message with no records. It copied the number tokens, left the planted instructions alone and returned bare records with no fence.

Note: Twenty-two inputs written by us, all data invented (14 traps, 8 controls): pretty-printed, glued and array inputs, fences and chat text, single quotes, comments, Python literals, big integers, planted instructions, five cut-off last records, a repeated key, a leading-zero number and an input with no records. Each answer is scored by code: record count, every leaf value, number tokens that must survive, and the exact CANNOT REPAIR line for the refusals. Rules re-checked on 2026-10-08 in the JSON Lines convention, the NDJSON specification and RFC 8259 (no leading zeros, repeated names unpredictable). The no-skill side was scored with the code fence removed first. One check was widened after the run for BOTH sides: for the record cut off only before its last closing brace, either the refusal or the exact closed record with no added field is accepted, because closing that one brace invents nothing. One run per model and input.

### With and without the skill

Tested 2026-10-08.

- Inputs repaired right (22 inputs): Sonnet 22/22 with, 15/22 without; Haiku 22/22 with, 15/22 without.

Same request on both sides. Read by hand, Sonnet without the skill already did every plain repair, copied number tokens, quoted a leading-zero ZIP code whose neighbours were text, and closed the record cut off only before its final brace without adding a field. It missed the cases where the data decides: it dropped a cut-off last record without saying so (twice), invented the end of two others (a closed array, a null), kept the last value of a repeated key, turned 007 into 7, and turned 'Error 503' into a record. Haiku missed the same cases and two more: it finished the cut name Ol as a record and re-wrote 1e2 as 100 and -0 as 0. It quoted 007 as text, one of two readings, picked silently.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

Full summary: https://aiskills402.com/skills/jsonl-repair/tests

## Example

### English (claude-sonnet-5-5)

Before:

> {"id":1,"name":"Café","price":1.10,"tags":["a","b"]} {"id":2,"name":"Mira","price":20,"tags":[]} {"id":3,"name":"Tom","price":3.50,"tags":["c"],"meta":{"x":null}}

After:

> {"id":1,"name":"Café","price":1.10,"tags":["a","b"]} {"id":2,"name":"Mira","price":20,"tags":[]} {"id":3,"name":"Tom","price":3.50,"tags":["c"],"meta":{"x":null}}

### Bulgarian (claude-sonnet-5-5)

Before:

> {'град': 'София', 'активен': True, 'бележка': None} {'град': 'Пловдив', 'активен': False, 'бележка': 'ул. „Тракия“ 5'}

After:

> {"град":"София","активен":true,"бележка":null} {"град":"Пловдив","активен":false,"бележка":"ул. „Тракия“ 5"}

## What is in the file

- The format you produce
- Hard rules
- Repairs
- Work in this order
- Short examples

## Languages

Any language

## How to buy

Agent (HTTP):

1. GET https://api.aiskills402.com/v1/skills/jsonl-repair/file without a payment header. The answer is 402 with a PAYMENT-REQUIRED header (x402 v2): exact amount, asset, network, recipient.
2. Sign `accepts[0]` with an x402 client (for example @x402/core + @x402/evm).
3. Repeat the GET with the signature in the PAYMENT-SIGNATURE header. The answer is 200 with the file, its sha256 and a re-download token.

Agent (MCP): https://mcp.aiskills402.com/mcp — free tools search_skills, get_skill, redownload_skill. Buying itself is over HTTP.

Full flow: https://aiskills402.com/docs

## The file

- Version: 1.0.0
- Size: 8.0 KB (8186 bytes)
- SHA-256: 0df6e4f0c779df7930466f09beae4d7daf470c5a22a427542886ac24548536a6
- Updated: 2026-10-08
- New versions are free through your re-download token.

## Versions

### 1.0.0 (2026-10-08)

First draft: repairs broken JSON Lines (NDJSON) record by record without changing a value. Re-joins pretty-printed records, splits glued records, unwraps an array, drops blank lines, fences and chat text, fixes trailing commas, single quotes, unquoted keys, comments and Python literals. Numbers are copied as written. A cut-off last record, a repeated key and an undecidable leading-zero number get a fixed CANNOT REPAIR line.

Rules checked on 2026-10-08 by read-only fetch of the JSON Lines convention (UTF-8, no byte order mark, one value per line, line feed terminator, blank lines are not values), the NDJSON specification (records never contain raw line breaks, parsers may skip empty lines, UTF-8) and RFC 8259 (number grammar without leading zeros, section 4: names within an object should be unique and behaviour on repeats is unpredictable, section 6: only integers up to 2 to the 53rd minus one interoperate).

Test cases: 22 (14 traps, 8 controls); not yet run on a model. Price is the starting price and is set after the baseline run.

## License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Terms: https://aiskills402.com/docs#license

## FAQ

### What happens when the final record is cut off?

You get one line that begins with CANNOT REPAIR: followed by the input line where the record begins. Nothing is closed, dropped or guessed, and the earlier records are not handed back as if the file were whole, so a program that reads the first line knows a person has to look. In a training set or a log, one invented row does more harm than a stopped job, because nobody sees it.

### Are my numbers and strings left alone?

Yes. Any number that is already valid JSON is copied exactly as written, so 1.10 stays 1.10, 1e2 stays 1e2 and an integer of twenty digits keeps every digit. A string such as "1,250" stays a string. A number with a leading zero is quoted only when the other records show that its field holds text, and otherwise the skill refuses instead of choosing between 7 and the text 007.

### How is it different from the JSON document skill?

The sibling skill repairs a single document and turns a value that was cut off into null. This one works per record, keeps the file a list of lines, and refuses a cut-off final record instead of nulling it. It also refuses a repeated key inside a record, because parsers disagree on which value wins, and it treats orders hidden in the data as plain data. Pick it when each line is a row that something else will read later, and pick the sibling when you hold one nested document.

### Does it help Claude Sonnet?

Without the skill Sonnet got 15 of 22 inputs right, with it 22 of 22. It already managed every plain repair and copied number tokens. It missed the cases where the data decides: a truncated final line (dropped silently or finished with invented values), a repeated key, the leading-zero 007, and an error message that it turned into a record. Haiku went from 15 to 22 the same way.

## Related skills

- [JSON Repair: Fix It, Keep Every Value](https://aiskills402.com/skills/json-repair.md): $0.05 once
- [CSV Repair: Fix the Form, Keep Every Cell](https://aiskills402.com/skills/csv-repair.md): $0.05 once

## Measurement limits

- Models other than the two named above were not run.
- Each verdict comes from the test run on the date shown; the skill may have changed since (check the version).
- Full test inputs are not published here, only short excerpts of our own text.
- Results on your own texts, languages and domains can differ.

Offer note: Paid in USDC (USD-pegged) over x402 by an AI agent; one-time.
