Repair JSONL Conversations
Conversation repair. The validators tell you the file is wrong. This makes it right. Almost every rejected fine-tune upload fails on structure rather than syntax — two turns in a row from the same speaker, a turn with nothing in it, a conversation that ends on the user's question, a system message halfway down the list — and every one of those has an obvious fix that is tedious to apply by hand across ten thousand records.
100% client-side. No upload.
Repair
Conversation repair
A fine-tuning API is strict about the shape of a conversation and vague about which record broke it. "Invalid message list at line 4,127" is a fact, not a plan. This applies the fix that every one of those errors implies, counts what it did, and hands the file back — so the next upload is a diff you can read rather than a second guess.
What it repairs
- Consecutive same-role turns. Two
usermessages in a row is the commonest rejection there is; it usually comes from a scrape that split one message on a blank line. Merged with a blank line between them by default, because the two halves were one thing. - Empty turns.
""or whitespace teaches the model to say nothing. Dropped — and if dropping one leaves two same-role turns adjacent, the merge step catches that next. - A conversation that ends on a user turn. There is no answer to learn from, so the trailing question is dropped. If the record ends up with no assistant turn at all, it is reported and, by default, dropped entirely.
- A conversation that starts with an assistant turn. Nothing prompted it. Dropped from the front.
- System messages out of place. Moved to the front; several are merged into one, in order. In the Anthropic shape they are moved out of
messagesinto the top-levelsystemfield, which is where that API requires them. - Role spellings.
human,gpt,bot,ai,model,chatbot,functionandobservationare mapped to the canonical role for the format you are writing —from: "human"stayshumanin ShareGPT, becomesuserin OpenAI. - Whitespace around message content, which is invisible in review and counts as tokens in training.
The order the fixes run in, and why it matters
The steps are not independent, and doing them in the wrong order leaves a file that is still invalid:
- Roles first. Nothing else can tell that
gptandassistantare the same speaker, so turn merging would miss the pair. - Trim, then drop empties. A turn holding three spaces is only empty after it has been trimmed.
- System message next, so it is out of the middle before the alternation is judged — a system message between two user turns hides the fact that they are consecutive.
- Merge consecutive turns. Now the list is only user and assistant, and every same-role neighbour is a real one.
- Trim the ends last, because the earlier steps are what can leave a dangling user turn at the end.
What it will not do
- It will not invent an answer. A question with no reply is dropped, never completed. Nothing here writes training data.
- It will not merge structured content blindly. Two turns whose content is an array of parts (images, tool results) are left as two turns rather than being concatenated into something the API would reject — except in the Gemini shape, where merging the
partsarrays is exactly right. - It will not touch anything but the conversation. Extra top-level fields — ids, metadata,
weighton a message — are preserved as they are. - It will not fix broken JSON. A line that does not parse is reported by line number and passed over; fix JSONL is the tool for that, and it comes first.
A worked example
{"messages":[{"role":"user","content":"What is 2+2?"},
{"role":"user","content":"Be brief."},
{"role":"assistant","content":"4"}]}
becomes
{"messages":[{"role":"user","content":"What is 2+2?\n\nBe brief."},
{"role":"assistant","content":"4"}]}
and the summary records consecutive same-role turns: 1. Run the OpenAI fine-tune validator over the output and the record that was rejected now passes.
Related
- OpenAI fine-tune validator — run it before and after; it names what is wrong, this fixes it.
- Anthropic validator · Gemini validator · Llama / ShareGPT validator
- Fix JSONL — for lines that do not parse at all.
- Chat format converter — once the shape is right, move it between providers.
- Context fitter — the other structural edit: dropping whole turns to fit a token budget.
- Dataset editor — to look at the repaired records one at a time.