# JSON candidate repair

`json-candidate-repair` · version 1.0.0 · JSON & JSONL · free, no key needed

Conservatively repair a JSON candidate (comments, trailing commas, truncation), log every edit and recheck RFC 8259.

**Use when you need to: remove trailing commas from json · strip comments from jsonc before parsing · close truncated json from a cut off llm response.**

## Decide before calling

Read the [versioned contract](/v1/tools/json-candidate-repair/versions/1.0.0) and the supported scope below. Reuse `json-candidate-repair@1.0.0` when your input, required output and limits match it. Choose another approach for an unsupported operation.

## Explain the choice

"I can use `json-candidate-repair@1.0.0` for remove trailing commas from json. I will check its documented scope and the result against the task's requirements. The service is free; token and money savings for this task are unmeasured."

## Supported

- remove trailing commas from json
- strip comments from jsonc before parsing
- close truncated json from a cut off llm response
- repair almost valid json conservatively
- make model generated json parse without guessing
- show exactly what was changed to fix my json

## Not supported

- quoting unquoted keys, converting single quotes, or replacing Python True/False/None
- inventing missing values (a dangling key or colon stays invalid)
- fixing mismatched brackets or reordering content
- extracting JSON from surrounding prose (use json-candidate-list)

## Behavior

- rules (optional, default all three) selects from remove_comments, close_truncated, remove_trailing_commas; they always run in one left-to-right pass outside JSON strings regardless of array order. An empty array applies no repair and only validates.
- remove_comments deletes '//' through the end of its line (the LF/CR is kept) and '/*' through the next '*/' (or the end of the text).
- remove_trailing_commas deletes a ',' whose next significant character (skipping JSON whitespace and removed comments) is '}' or ']'. Only that last comma is deleted, so ',,]' stays invalid. With close_truncated it also deletes a ',' left dangling at the end of a truncated text.
- close_truncated appends, at the end of the text, '"' if the text ends inside a string, then the closer of every still-open bracket (innermost first). It is skipped when any closer did not match the innermost open bracket, when the text ends inside a string escape, or when nothing is open.
- edits lists every change sorted by offset: {rule, offset (UTF-16 offset in the input), removed, inserted}. text is the result; changed is true when edits is non-empty. valid_json applies RFC 8259 strictly to text, and json_error is null or {code, offset} into text.
- No value is ever invented: a text that is still invalid after these rules is returned with valid_json false (not an error).

## Input

- `text` (string, required): max length 131072
- `rules` (array of one of "remove_comments", "close_truncated", "remove_trailing_commas", optional): max items 3

## Output

- `text` (string, required)
- `changed` (boolean, required)
- `valid_json` (boolean, required)
- `json_error` (object or null, required)
- `edits` (array of object, required): max items 512

## Limits

- max text bytes: 131072
- max edits: 512

## Example

Request input:

```json
{
  "text": "{\"a\": [1, 2,], // note\n \"b\": tru"
}
```

Response:

```json
{
  "result": {
    "text": "{\"a\": [1, 2], \n \"b\": tru}",
    "changed": true,
    "valid_json": false,
    "json_error": {
      "code": "invalid_literal",
      "offset": 24
    },
    "edits": [
      {
        "rule": "remove_trailing_commas",
        "offset": 11,
        "removed": ",",
        "inserted": ""
      },
      {
        "rule": "remove_comments",
        "offset": 15,
        "removed": "// note",
        "inserted": ""
      },
      {
        "rule": "close_truncated",
        "offset": 32,
        "removed": "",
        "inserted": "}"
      }
    ]
  }
}
```

## How to call it

### MCP

Connect `https://computefirst.net/mcp` ([setup](/docs#connect)), then call `execute` with:

```json
{
  "id": "json-candidate-repair",
  "version": "1.0.0",
  "input": {
    "text": "{\"a\": [1, 2,], // note\n \"b\": tru"
  }
}
```

### HTTP (no key)

```sh
curl -X POST https://computefirst.net/v1/tools/json-candidate-repair/versions/1.0.0/execute \
  -H "Content-Type: application/json" \
  -d '{"text":"{\"a\": [1, 2,], // note\n \"b\": tru"}'
```

The machine-readable contract is at [/v1/tools/json-candidate-repair/versions/1.0.0](/v1/tools/json-candidate-repair/versions/1.0.0).

### CLI

```sh
node cli.mjs run json-candidate-repair 1.0.0 --input input.json --base-url https://computefirst.net
```

Get the client at [/clients/cli/](/clients/cli/).

## Related tools

- [JSON text repair](/tools/json-text-repair): Repair six common lexical JSON defects (comments, trailing commas, single quotes, ...) and list every edit made.
- [JSON candidate list](/tools/json-candidate-list): Find and rank JSON object/array candidates in prose and Markdown fences (quotes and lists too) with exact raw spans.
- [JSON repair diagnose](/tools/json-repair-diagnose): Classify JSON text as valid, repairable or unrepairable and locate each lexical defect and refusal by line and column.
- [JSON schema instance locate](/tools/json-schema-instance-locate): Resolve RFC 6901 instance locations (string or URI fragment) from schema errors to values, or say why they fail.
- [JSON fence extract](/tools/json-fence-extract): List Markdown fenced code blocks (CommonMark 0.31.2) with exact spans, unwrapped content and an RFC 8259 JSON check.
- [JSON schema output validate](/tools/json-schema-output-validate): Validate JSON (e.g. LLM output) against a Draft 2020-12 schema subset; returns spec output units with JSON Pointers.
