FlyingFish Space
Back to Guides

Why Our AI JSON Repair Sometimes Refuses to Help — On Purpose

AD
Developer Tool

JSON Pipeline — A practical toolkit for working with JSON.

Clean, repair, transform and validate JSON without adding unnecessary friction.

JSON Clean AI Repair Transform Schema
Explore JSON Pipeline →
Quick Reference

The short version: AI-generated content is inherently non-deterministic. If your system doesn't account for that, an AI repair tool can fail in the worst possible way — not with an error, but with a plausible-looking, silently wrong result.
Our answer: value-locking on every field, a calibrated hard limit on batch size, and a simple rule that governs both: reject rather than silently corrupt.

Most discussions about AI reliability focus on accuracy — did the model get the right answer? That's the wrong question for a repair tool. The right question is: when the model is wrong, how does your system find out, and what does it do next?

This is the story of how we found a gap in our own answer to that question, and the two guardrails we built to close it.

1. The Problem: When "It Worked" Isn't Good Enough

Our AI-assisted repair endpoint exists for one reason: rule-based JSON repair can fix syntax, but it can't fix semantics. If a field says status: "urgent" and your schema only allows ["low", "medium", "high"], no regular expression is going to figure out that "urgent" probably means "high." That takes a language model.

Handing a semantic decision to a language model is a reasonable trade. Handing it a decision with no way to verify the result is not. Most JSON repair tools — including the open-source rule-based libraries this space is full of — don't need to worry about this, because they don't touch semantics at all. The moment you add an AI model into a repair pipeline, you've added a component that can be confidently, plausibly wrong.

We already had one layer of defense against this: our repair engine never lets the AI invent a value for a field that was genuinely missing from the input, and never lets it silently change a value it wasn't authorized to touch. What we hadn't fully mapped out was what happens when the model runs out of room mid-repair.

2. What We Found: Failure Without an Error

Language models don't generate output all at once — they generate it token by token, against a finite output budget. For most requests, that budget is never an issue. But when we started systematically testing larger batch repairs — arrays of dozens or hundreds of records in a single request — we found a failure mode that doesn't look like a failure at all.

When a repair task is large enough, the model can exhaust its output budget partway through generation. Depending on exactly where that cutoff lands, the response can come back empty, malformed — or, in the more concerning case, syntactically complete but content-altered: fields that should have been left untouched get rewritten or compressed, not because the model decided to "fix" them, but because it was working within limits it never actually had room to work within.

This is the failure mode that matters most for a repair tool. An empty response is annoying but obvious — you retry. A response that looks fine but quietly rewrote content you never asked it to touch is the kind of bug that ships into production, gets logged as "success," and surfaces three weeks later as a data integrity incident nobody can explain.

We ran this down through systematic batch-size calibration — testing repeated, controlled batches at increasing sizes and output budgets, watching for the point where results stopped being reliably complete and unaltered. The unstable zone showed up well before we expected it to, and it wasn't a hard, predictable line — reliability degraded probabilistically as batch size grew, which meant no single output-budget setting alone could fully solve it. Reliable capacity had to be measured, not assumed.

3. Two Guardrails, Not One

The fix isn't a single setting. It's two independent checks that catch different failure shapes.

3.1 Value-Lock

Every AI-assisted repair we run is checked field-by-field against the original input. The model is only permitted to fix structure, rename or restructure keys, and — only when your schema explicitly declares an enum — remap a non-conforming value to something the schema allows. Any other field that comes back altered causes the entire repair to be rejected, not silently accepted with a footnote.

{
  "success": false,
  "error": "AI repair rejected: changed protected value(s) at accountType"
}

This is what caught the truncation problem in the first place — not a monitoring dashboard, but the same guardrail that was already there to catch a completely different kind of error. That's not a coincidence; a single principle (never accept a change you can't verify was intentional) turned out to defend against multiple failure causes.

3.2 A Calibrated Batch Limit

Value-lock catches bad output after the fact. The second guardrail prevents the risky condition from happening at all: input to our AI repair endpoint is capped at a fixed size — well below the platform's general 1MB payload limit — based directly on the calibration testing described above, not a round number picked in advance.

{
  "success": false,
  "error": "Input exceeds the AI repair size limit (3072 bytes; received 5880 bytes). Please split large inputs into smaller batches and repair them separately."
}

Oversized input never reaches the model at all. It's rejected immediately, before any AI call is made — which also means it's never charged. If you need to repair a larger document, the answer is to split it into smaller batches, not to hope the model handles the whole thing correctly.

4. The Trade-Off We Chose — And Who It's For

We want to be direct about what this costs: some requests that a more permissive system would "handle" get rejected by ours. A batch that's a little too large doesn't get a best-effort attempt — it gets a 413 and a suggestion to split it up.

We think that's the right trade for the kind of integration this tool is built for. If you're feeding repaired JSON into a database, a billing pipeline, or anything downstream that assumes the data it receives is correct, a loud, immediate rejection is far easier to handle than a quiet, delayed corruption. You can catch a 413 in your error handling in five minutes. You cannot easily catch "some records in this batch have subtly different note fields than what was submitted," because nothing told you to look.

If what you need instead is a tool that always returns something and you're comfortable spot-checking the output yourself, that's a legitimate choice too — it's just not the trade-off we made here. We'd rather tell you no than tell you a wrong yes.

5. The Principle Behind It

This isn't an isolated fix. It's the same rule that already governs how this platform handles numeric precision: JSON's number type can't exactly represent values beyond about 15 significant digits, and rather than silently round a value that exceeds that and hand back a number that's quietly wrong, every endpoint on the platform rejects the input outright.

Precision guarding, value-locking, and calibrated batch limits are three implementations of one idea: reject rather than silently corrupt. None of them make the underlying language model more accurate. What they do is make sure that when it isn't accurate, you find out immediately — not after the bad data has already gone somewhere it shouldn't have.

Want to see how this plays out in practice? The AI-assisted JSON repair tool and its full API documentation — including the Guardrails section — are free to try, no login required.

📖 You Might Also Like