json_repair: A Python fallback that fixes the JSON your LLM actually emitted
Repair malformed JSON from LLMs, APIs, logs, and user input in Python.
At a glance
- What is it?
- json_repair is a Python library that turns malformed JSON from LLMs, logs, and user input into valid structures. It works as a drop-in replacement for json.loads(), but you need to know when to skip its validation fast path.
- Who is it for?
- Adopt json_repair if you build pipelines that consume LLM-generated JSON and you cannot guarantee strict syntax from the model. Skip it if your inputs are already valid or if you need deterministic, schema-enforced output.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Python, 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
Why JSON from LLMs breaks and what this library targets
Large language models frequently emit JSON that is almost valid: a missing closing bracket, an extra comma, a stray sentence before the opening brace, or a truncated string. Standard json.loads() rejects all of that. json_repair exists to fix those specific, repetitive mistakes without losing the content. The README states that the mistakes LLMs make are simple enough to be fixed without destroying the content. The library targets developers who receive JSON from LLMs, APIs, logs, or direct user input, where the producer is not a guaranteed parser. It is not a validator and not a schema enforcer. It is a repair heuristic that tries to turn broken text into a Python object or a valid JSON string.
The repair mechanism: strict parse first, then a forgiving parser
The core design is a two-stage process. By default, json_repair.loads() and repair_json() first attempt the standard library json.loads(). If that succeeds, the input is returned immediately. Only on a JSONDecodeError does the library run its own repair parser. This is a deliberate choice: the README explicitly calls out the antipattern of wrapping json.loads() in a try/except and then calling json_repair.loads() as wasteful, because json_repair already performs that strict check internally. The repair parser itself handles missing quotes, misplaced commas, unescaped characters, incomplete key-value pairs, and stray prose. It also recognizes Python-style tuples: a comma-separated parenthesized sequence becomes a JSON array, while a single parenthesized value stays a scalar. Within arrays, objects, and tuples, true, false, null, and None are recognized case-insensitively as JSON booleans or null. That means the parser is not just patching syntax; it is making semantic guesses about what the model intended.
Getting started: install, basic calls, and file input
Installation is a single pip command: pip install json-repair. The package name uses a hyphen, while the import uses an underscore. The simplest usage is to replace json.loads() directly: import json_repair; decoded_object = json_repair.loads(bad_json). The README gives an example where a string with a trailing comma and a missing closing brace decodes to a Python dict. You can also call repair_json() to get a string back, or pass return_objects=True to get a Python object directly. For file handling, json_repair.load() is a drop-in replacement for json.load(), and json_repair.from_file() reads from a file path. The documentation warns that IO exceptions are not caught by the library, so you must manage file open errors yourself. All parameters accepted by json.dumps() are passed through, including indent, which is useful for pretty-printing repaired output.
The non-Latin character trap and ensure_ascii
A critical detail that can silently corrupt data is the handling of non-Latin characters. The README shows that repair_json("{'test_chinese_ascii':'统一码'}") returns {"test_chinese_ascii": "\u7edf\u4e00\u7801"}, which is ASCII-escaped Unicode. That is valid JSON but not human-readable. To preserve the original characters, you must pass ensure_ascii=False. This mirrors the standard json.dumps() behavior, but it is easy to miss because json.loads() never escapes by default. If your pipeline handles Chinese, Japanese, Korean, or any non-Latin script, forgetting this parameter will turn all your strings into escape sequences. That may break downstream consumers that expect raw text, or it may just make debugging harder. The README flags this explicitly, which suggests it is a common oversight.
Performance tradeoff: skip_json_loads and when to use it
The default flow runs the standard json.loads() first, which is fast for valid JSON but adds an extra parse pass for invalid input. If you know ahead of time that your input is malformed, you can pass skip_json_loads=True to repair_json(). This skips the validation fast path and goes straight to the repair parser. The README calls this an explicit tradeoff and warns that skip_json_loads=True is only for inputs you already know are invalid. If you force it on valid JSON, you will run the slower repair parser unnecessarily. In practice, LLM output is often invalid, but not always. The right choice depends on your mix. If you process a high volume of mostly valid JSON, keep the default. If you are repairing a stream of known-broken model output, skip_json_loads=True will save a wasted parse. The README does not provide benchmark numbers, so you need to measure on your own payloads.
Limitations: silent data changes and no schema guarantee
The library's strength is also its weakness: it guesses. When the parser encounters a missing value, it auto-completes with defaults like empty strings or null. That means a repaired object may contain fields the original producer never intended. For example, an incomplete key-value pair could become a key with an empty string value, and you cannot tell whether the model meant to omit it or just got cut off. The README says the parser recognizes None as null, which is convenient for Python users but could mask a genuine None string in the source. There is no schema validation built in. json_repair will happily return a structure that is valid JSON but semantically wrong for your application. If you need to enforce types or required fields, you must pair it with a schema validator like pydantic or jsonschema. The library is also not designed for adversarial input: it assumes the malformation is accidental, not malicious. A crafted string could produce unexpected structures.
Alternatives and the difference in approach
The main alternative is to not repair at all and instead force the LLM to produce valid JSON using constrained decoding or structured output. Libraries like Outlines or Guidance use grammar-based sampling to guarantee that the model's output matches a JSON schema token by token. That approach eliminates the need for repair altogether, because invalid JSON is never generated. json_repair takes the opposite stance: let the model generate freely, then fix the result. That is simpler to integrate into an existing pipeline, but it shifts the risk to the repair step. Another alternative is to write your own regex-based fixer, which is what many teams do before discovering json_repair. But hand-rolled fixers tend to be brittle and fail on edge cases the library already handles, such as Python-style tuples and case-insensitive booleans. The real decision is whether you can afford to reject invalid output and retry the model, or whether you must accept whatever comes back. If you can retry, constrained decoding is more reliable. If you cannot, json_repair is a pragmatic fallback.
Maintenance, license, and upgrade cost
The repository is MIT-licensed, which means you can use it in commercial projects without copyleft obligations. The project is actively maintained, with releases in August 2026 and a last push in September 2026. That signals ongoing attention, but you should still pin a specific version in your dependencies rather than floating on latest. The README mentions that the library is maintained as a side project, so feature requests may not get immediate responses. The API surface is small, which keeps upgrade cost low: the main functions are loads(), load(), from_file(), and repair_json(). The behavior of the repair parser could change between minor versions, especially if new heuristics are added. Before upgrading, run your test suite against the new release. The documentation also asks for sponsorship, but that does not affect the license or availability. As a side project, there is no formal support channel, so you must be prepared to debug issues on your own or rely on the community.
Editorial conclusion
Adopt json_repair if you build pipelines that consume LLM-generated JSON and you cannot guarantee strict syntax from the model. Skip it if your inputs are already valid or if you need deterministic, schema-enforced output. Before adopting, verify that the repair heuristics match your failure modes: test with your actual model outputs, check whether ensure_ascii=False is needed for non-Latin text, and measure the cost of the default json.loads() fast path on your largest payloads. The library is MIT-licensed and actively maintained, but its core value is a best-effort repair that may silently change data types, so treat it as a fallback, not a validator.
Community notes