Data & Analysis

CSV to JSON Rows: Every Cell Stays Text

Converts CSV into a JSON array with one object per row, keyed by the header, and answers with the JSON only, no code fence. Every value stays a string exactly as the cell reads, so 007, 1,250, 1.10, TRUE, null, dates, spaces around a name and a value that starts with an equals sign are never turned into numbers, booleans or null, and an empty cell is an empty string. Only a column the task names as integer, number or boolean is converted. Quotes are removed, doubled quotes become one quote, line breaks inside a quoted cell become backslash n. Semicolon and tab files, a byte order mark, CRLF rows and a trailing blank line are handled. A short or long row, a duplicate header name, an unclosed quote, a typed cell that does not fit its type and text that holds no table get a fixed one-line CANNOT CONVERT answer instead of invented or null values. Use when an agent must load a CSV export into code, an API or a database, or when asked to turn CSV into JSON.

CSV to JSON Rows: Every Cell Stays Text is a tested SKILL.md that converts CSV into a JSON array with one object per row, keyed by the header, and answers with the JSON only, no code fence; an agent buys it once for $0.03 over x402.

Tested 2026-10-08No code, no hidden instructionsv1.0.0 · 8.6 KB · perpetual license

Not for

Guessing column types, parsing dates or currencies, removing duplicates, sorting or summing rows; Excel or ODS files; repairing a broken CSV. Columns are converted only when your task names them as integer, number or boolean. Ragged rows, a repeated header name, an unclosed quote, a typed cell that does not fit and text with no table end in CANNOT CONVERT. Based on RFC 4180 and 8259.

Tested, honestly

Tested 2026-10-08 with a strong and a weak model.

With and without the skill

Results with and without the skill, for Sonnet and Haiku
SonnetHaiku
withwithoutwithwithout
Setups converted right (22 setups)22/2220/2222/2220/22

Same request on both sides; the bare side had the fence removed first. Read by hand, Sonnet without the skill already kept every cell as text (007, 1,250, 1.10, TRUE, null, NaN, dates), read quoted line breaks, doubled quotes, semicolon files, the byte order mark and the CRLF rows, converted the typed columns right and ignored the planted comment. It missed two traps: with a header that repeats a name it wrote objects with the same key twice, so a parser keeps only the last value, and with an unclosed quote it swallowed the remaining rows into one cell and gave one row instead of three. Haiku without the skill made the same two mistakes and nothing else. Once the task stated the refusal rule, both bare models refused the short row, the long row, the prose and the bad typed cell, so on those four the skill adds nothing.

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.

SonnetStrong model, claude-sonnet-5-5
Right on all 22 setups, read by hand: it kept 007, 1,250, 1.10, TRUE, null, NaN, dates and a formula-like cell as text, kept the spaces around names, wrote a line break inside quotes as backslash n, undoubled quotes, split semicolon and tab files, read a decimal comma as one cell, dropped the byte order mark and the empty last line, converted only the three named columns, padded a short row only when told to, answered a header-only file with an empty array, refused a repeated header name and an unclosed quote with the one-line CANNOT CONVERT, and treated a comment aimed at the AI as plain text. With the refusal rule stated in the task it also refused a short row, a long row, prose that holds no table and a typed cell that does not fit.
HaikuWeak model, claude-haiku-5-5
Right on all 22 setups, read by hand, with the same answers as Sonnet: strings kept exactly, typed columns converted only where named, the repeated header name and the unclosed quote refused in the fixed one-line form, and the planted comment treated as text. It refused the short row, the long row, the prose and the bad typed cell as well.

Full test summary

Example

Our own test text, before and after the skill ran. Excerpts only.

English · claude-sonnet-5-5

Before

id,code,amount,flag,note,date,hex 1,007,"1,250",TRUE,,2026-10-08,0x1F 2,0012,1.10,null,"=SUM(A1:A2)",08/10/26,1e5 3,01234,-0,false,"",00:15,NaN

After

[{"id":"1","code":"007","amount":"1,250","flag":"TRUE","note":"","date":"2026-10-08","hex":"0x1F"},{"id":"2","code":"0012","amount":"1.10","flag":"null","note":"=SUM(A1:A2)","date":"08/10/26","hex":"1e5"},{"id":"3","code":"01234","amount":"-0","flag":"false","note":"","date":"00:15","hex":"NaN"}]

Bulgarian · claude-sonnet-5-5

Before

номер;име;град;сума 1;Мария;София;1 250,00 2;Иван;Пловдив;"07,5" 3;Калина;Варна;

After

[{"номер":"1","име":"Мария","град":"София","сума":"1 250,00"},{"номер":"2","име":"Иван","град":"Пловдив","сума":"07,5"},{"номер":"3","име":"Калина","град":"Варна","сума":""}]

German · claude-sonnet-5-5

Before

Nr,Name,Ort 1,Anna,"Köln, Nord" 2,Bernd,Bonn

After

[{"Nr":"1","Name":"Anna","Ort":"Köln, Nord"},{"Nr":"2","Name":"Bernd","Ort":"Bonn"}]

Spanish · claude-sonnet-5-5

Before

id,nombre,ciudad 1,José,Málaga 2,Lucía,Sevilla

After

[{"id":"1","nombre":"José","ciudad":"Málaga"},{"id":"2","nombre":"Lucía","ciudad":"Sevilla"}]

What is in the file

  • Hard rules
  • Reading the CSV
  • When to refuse
  • Work in this order
  • Short examples

Languages

Any language. Tried in: English, Bulgarian, German, Spanish.

License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.

Versions

Current version 1.0.0, updated 2026-10-08. Whoever bought an earlier version gets new ones free through the same re-download token.

  1. v1.0.0 · 2026-10-08

    First release: converts CSV into a JSON array of objects keyed by the header. Every value stays a string exactly as the cell reads (007, 1,250, 1.10, TRUE, null, dates, spaces, formula-like values); an empty cell is an empty string; only columns the task names as integer, number or boolean are converted. Semicolon and tab files, a byte order mark, CRLF rows, quoted line breaks and doubled quotes are handled. A short row, a long row, a duplicate header name, an unclosed quote, a typed cell that does not fit its type and text with no table get a fixed one-line CANNOT CONVERT answer.

    Rules checked on 2026-10-08 against RFC 4180 and RFC 8259 (read-only fetch of both texts). RFC 4180: records separated by line breaks, the last line break optional, a header with the same field count as the records, spaces are part of a field, fields with line breaks, double quotes or commas are enclosed in double quotes, a quote inside is doubled, a bare field may not contain a quote. RFC 8259: an object is an unordered collection and its names SHOULD be unique (so a duplicate header is refused, and key order is free in the checks); a string must escape the quotation mark, the reverse solidus and U+0000 to U+001F (so a line break in a cell is written backslash n). Not from the RFCs, our own decisions: all values strings by default, refusing short and long rows (padding only when the task says so), refusing a typed cell that does not parse, a blank line between rows read as a short row, a byte order mark dropped, an empty last line not a row.

    Test set: 22 cases (15 traps, 7 controls), checked by a JSON schema (key order free, types strict). Model results: to be added after the baseline run.

FAQ

Are 007, 1,250 and TRUE kept as text?

A parser on the other side cannot tell that 007 was a product code and not the number 7. Zip codes, phone numbers, order references, a price typed as 1,250 and a flag typed as TRUE all change meaning once they turn into numbers or booleans, and no error tells you. So each cell is copied as written, spaces around a name stay, an empty cell becomes an empty string and never null. If you do need numbers, name the column and its type in the task. Only that column is converted, and a cell such as n/a in it stops the conversion and names the row. Nothing is trimmed, rounded or reformatted anywhere.

What happens with a row that has too few or too many cells?

You get a single line beginning with CANNOT CONVERT that names the row, because every way of filling the gap shifts values into the wrong column without any error. When your task tells the skill to pad short rows, the missing cells at the end become empty strings. A row with extra cells, a header that repeats a name, a quote that never closes, a blank line between rows and a typed cell that is not a valid integer, number or boolean end the same way, so a person looks at the file before it reaches a database.

Does it handle semicolon files, tabs, quoted line breaks and typed columns?

Yes. The separator is whichever character cuts the header and every row into the same count of fields, so 12,50 stays one cell in a semicolon export. Outer quotes disappear, a doubled quote becomes one quote, and a line break inside quotes becomes backslash n. A byte order mark and an empty last line are absorbed. Name a column and a type in your task, such as qty as an integer, and only that column is converted; a zip code beside it keeps its leading zero. Thousands separators, decimal commas and words like n/a are never guessed into numbers; the row is named instead.

Does it help Claude Sonnet?

Two traps out of twenty-two made the difference. Sonnet scored 20 of 22 setups bare and 22 of 22 with the file loaded. On its own it knew that 007, 1,250 and TRUE stay text, how quoted line breaks and doubled quotes work, semicolon and tab files, and which columns to convert when the task names them. It missed two traps: a header that repeats a name (it wrote the same key twice, so a parser keeps one value) and an unclosed quote (it merged the remaining rows into one cell). Haiku went from 20 to 22 on the same setups.

Share

Read this page as Markdown: /skills/csv-to-json-rows.md.

  • CSV Repair: Fix the Form, Keep Every Cell

    Data & Analysis

    SKILL.md · v1.0.0 · 8.3 KB

    Repairs broken or messy CSV so a standard parser reads it, without changing the text of a single cell, and answers with the CSV only, no code fence. Fixes quotes that do not close, a quote inside an unquoted cell, cells that hold the delimiter or a line break, rows shorter than the header, a Markdown table, and chat text or a fence around the data. Numbers such as 1,250, 007 and 1.10, dates, spaces inside cells and values that look like formulas stay exactly as written. Semicolon and tab files keep their delimiter. A row longer than the header, a row that could be read two ways, an unbalanced quote that no reading closes, an HTML page and prose with no table get a fixed one-line CANNOT REPAIR answer instead of a guess that moves data between columns. Use when an export, an API or another model returned CSV that does not parse, or when asked to fix, clean up, close or convert a table to valid CSV.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026

  • Text to JSON: Extract Data Without Guessing

    Data & Analysis

    SKILL.md · v1.0.2 · 7.5 KB

    Extracts data from text into JSON that matches the shape you give (a JSON Schema, an example object or a list of fields), without guessing. Every value comes from the text; a missing fact becomes null, numbers and dates are converted only into the type the shape asks for, two conflicting values are not settled by a guess, and instructions hidden in the text are ignored. Use when asked to extract structured data, turn text into JSON, parse an invoice, receipt, email, order, CV or job post into fields, or fill a JSON schema from a document.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 3 Oct 2026

  • JSON Repair: Fix It, Keep Every Value

    Data & Analysis

    SKILL.md · v1.0.1 · 6.9 KB

    Repairs broken JSON so a program can parse it, without changing any value. Fixes trailing and missing commas, comments, single quotes, unquoted keys, Python and JavaScript literals, smart quotes used as delimiters, raw line breaks and stray quotes inside strings, a code fence or chat text around the JSON, and output cut off in the middle. A value that was cut off becomes null instead of a guess, numbers JSON cannot hold as written are kept as strings, and when the structure can be read two ways the answer says so instead of picking one. Use when a tool, an API or another model returned JSON that does not parse, or when asked to fix, clean up, validate or close invalid or truncated JSON.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 7 Oct 2026