json-repair: a Go library for salvaging malformed JSON from model output
🔧 Repair JSON!Solution for JSON Anomalies from LLMs.
At a glance
- What is it?
- json-repair is a zero-dependency Go package and CLI that rewrites broken JSON strings into parseable ones. It is a good fit for pipelines that cannot retry a model call, and a poor fit for anyone who needs to know whether the repair changed the meaning of the data.
- Who is it for?
- Adopt json-repair if you are parsing model output inside a Go service and a failed parse currently costs you a retry or a dropped record. Do not adopt it where the JSON is a contract with a downstream system that must fail loudly on malformed input, because the library returns a string rather than an error and will happily invent a closing bracket.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The failure json-repair is built around
Language models emit JSON-shaped text, not JSON. A response can arrive wrapped in a markdown fence, with single quotes instead of double quotes, with a trailing comma before the closing brace, or simply cut off mid-array because the model hit a token limit. Standard library parsers reject all of these, and in a Go service the rejection usually surfaces as an error that forces a retry, a fallback path, or a dropped record. json-repair exists to sit between the model response and the parser: it takes the raw string, applies a set of repairs, and returns a string that parses. The README frames the audience as Go developers who are already doing function calling, agent workflows or embedding pipelines, which is where unvalidated model text most often ends up inside a struct. The package is a port of the Python json_repair project, which the README names as its inspiration, so the repair rules follow a codebase that predates this one.
What the repair actually does to a string
The README's usage example is short: a string containing a fenced code block and an unterminated array, and a call to jsonrepair.RepairJSON that returns the closed, quoted object. The list of supported broken outputs is the most useful part of the documentation, because it doubles as a description of the internal repair passes. Those passes cover quote normalisation (single quotes and mixed quotes), control characters such as a line feed inside a string, unquoted keys and unquoted values, missing closing brackets for arrays and objects, a standalone left or right bracket, comments embedded in the object, and leading whitespace or list markers before the value. The roadmap entries confirm later additions: full-width character detection, smart or curly quote support, handling of multiple top-level JSON values, and duplicate key deduplication. That last one is the repair with the largest semantic footprint. If a model emits the same key twice, the library collapses it, and the README does not state which occurrence wins. Treat the output as a best-effort reconstruction of the model's intent, not as a faithful transcription of its bytes.
The API surface is deliberately two functions
jsonrepair.RepairJSON takes the broken string and returns a repaired string. MustRepairJSON is the variant the README recommends for pipes and trusted environments, which is a hint about the error model: the library is described as always giving a string result, so a caller who wants to distinguish a clean parse from a heavily rewritten one has to do that comparison themselves. There is no configuration struct, no option to disable individual repair passes, and no way to ask the library which rule fired. For a library whose whole job is guessing, that is a real gap. If a repair produces valid JSON with the wrong shape, nothing in the return value tells you a change was made. The practical mitigation is to keep the original string alongside the repaired one and compare them, or to validate the repaired output against a schema before it reaches the rest of your code. Neither step is provided by the package.
Installing the package and the CLI
For a Go project the README gives a single command: go get github.com/RealAlexandreAI/json-repair. The import path in the example is github.com/RealAlexandreAI/json-repair, and the call is jsonrepair.RepairJSON(in). For shell use there is a Homebrew tap, installed with brew install realalexandreai/tap-jsonrepair/jsonrepair, plus prebuilt binaries on the releases page. The CLI takes input two ways: jsonrepair -i "<raw string>" for a literal argument, and jsonrepair -f <json-file>.json for a file. The README notes that the command-line mode can be chained with pipes, which is the natural fit for a MustRepairJSON-style workflow where a non-zero exit is not useful. Note that the CLI example in the README shows an input with two names and an output with three, which does not match the library example above it; read that as illustrative formatting rather than a description of what the tool appends.
Where the repair approach breaks down
The library cannot tell you whether the model meant what it wrote. An unclosed array is repaired by adding a closing bracket, and an unclosed object by adding a closing brace, so a response truncated at the halfway point becomes a syntactically valid document containing roughly half the intended data. Downstream code sees a successful parse and no indication that anything was lost. The same applies to the duplicate key case and to the unquoted-value case, where the library has to decide how to quote a token the model left bare. A second limitation is scope: this is a Go package, so a Python, TypeScript or Java service gets nothing from it beyond the CLI as a subprocess. The README points to the Python json_repair project as the original, and anyone outside Go should look there first. A third is that the repair rules are heuristic and the README does not describe a formal grammar or a guarantee of termination on pathological input. The safest assumption is that the library handles the shapes listed in the README and that anything outside that list is untested territory.
Compared with retrying the model or using a schema
The obvious alternative is not another repair library, it is not repairing at all. Two common approaches: call the model again with a stricter prompt or a response format that constrains decoding, or validate the response against a JSON schema and reject anything that fails. Retrying costs latency and tokens but keeps the data honest, because a second response is generated rather than inferred. Schema validation costs nothing at inference time but still fails on the same malformed strings, which is precisely the case json-repair targets. The difference in approach is that json-repair treats malformed output as recoverable and schema validation treats it as a signal. In a workflow where the JSON drives a side effect, such as a function call with arguments, the schema-first approach is the one that fails safely. json-repair is the better choice when the JSON is advisory, when the cost of a retry exceeds the cost of a slightly wrong value, or when you are processing a batch of historical responses and cannot re-query the model.
Maintenance, versioning and the GPL-3.0 question
The repository is active and not archived, with a recent push in August 2026 and releases at v0.0.15, v0.0.16 and v0.0.17, the last two published within minutes of each other in June 2026. The version numbers are still in the 0.0.x range, which is a reasonable signal that the API and the repair rules can change between releases; pinning a specific version in go.mod is the low-effort way to avoid a surprise. The licence is GPL-3.0, and that is the detail most likely to affect adoption. GPL-3.0 is a copyleft licence: if you distribute a binary that links this package, the terms of that distribution are affected. Using it inside a service you operate rather than ship is a different situation from embedding it in a distributed CLI. This is not legal advice, and the boundary between linking and aggregation is exactly the kind of question to put to your own counsel before you depend on the package in a product you distribute.
Who should take the dependency
The clearest fit is a Go service that already calls a model and already has a fallback path for parse failures. json-repair replaces that fallback with an in-process repair, which removes a network round trip and keeps the latency profile flat. It is also a sensible fit for offline analysis of a corpus of model responses, where the alternative is throwing away records. The clearest non-fit is any pipeline where the JSON is a contract with a system that must fail loudly on malformed input, such as a payment instruction or a database migration, because the library's central design choice is to return a string instead of an error. Between those two, the deciding question is what a wrong value costs you. If it costs a log line, repair is fine. If it costs a reconciliation, validate first and repair only as a last resort. The one thing to check before adopting is the duplicate-key behaviour, since the README lists deduplication as a feature but does not say which value survives.
Editorial conclusion
Adopt json-repair if you are parsing model output inside a Go service and a failed parse currently costs you a retry or a dropped record. Do not adopt it where the JSON is a contract with a downstream system that must fail loudly on malformed input, because the library returns a string rather than an error and will happily invent a closing bracket. Before you commit, run your own worst-case payloads through RepairJSON and diff the output against the input, since the README lists the supported cases but does not promise that a repair preserves every value.
Community notes