> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JSON Recovery

> Automatic recovery system for malformed JSON generated by LLMs in tool calls

ChatCLI implements a **JSON recovery system** that automatically fixes malformed arguments generated by LLMs during tool calls. This dramatically increases the success rate of tool calls, especially with smaller models or via XML parsing.

***

## Why Malformed JSON?

LLMs frequently generate invalid JSON in their tool call arguments. This happens because language models work with tokens, not syntax validation:

| Problem                         | Example                                   | Frequency   |
| :------------------------------ | :---------------------------------------- | :---------- |
| Single quotes instead of double | `{'cmd': 'read'}`                         | Very common |
| Unquoted keys                   | `{cmd: "read", file: "main.go"}`          | Common      |
| Trailing commas                 | `{"cmd":"read","file":"main.go",}`        | Common      |
| Raw value without object        | `main.go` instead of `{"file":"main.go"}` | Frequent    |
| Mixed styles                    | `{cmd: 'read', "file": main.go}`          | Occasional  |
| CLI text instead of JSON        | `read --file main.go`                     | Frequent    |
| JS object literals              | `{cmd: read, file: main.go}`              | Occasional  |

<Warning>
  Without JSON recovery, these errors cause parsing failures that break the agent loop. With smaller models, up to 30% of tool calls may have invalid JSON.
</Warning>

***

## The 7 Recovery Strategies

The `NormalizeToolArgs` system applies up to 7 strategies in sequence, stopping at the first one that produces valid JSON:

<AccordionGroup>
  <Accordion title="1. Standard JSON Parse" icon="check">
    Attempts direct parsing with `json.Unmarshal`. If the JSON is already valid, it returns immediately without modifications.

    ```
    {"cmd":"read","args":{"file":"main.go"}}  =>  valid, returns directly
    ```
  </Accordion>

  <Accordion title="2. Single Quotes to Double Quotes" icon="quote-right">
    Converts single quotes to double quotes with proper escape handling. Preserves single quotes inside strings and escapes internal double quotes.

    ```
    Input:  {'cmd':'read','file':'main.go'}
    Output: {"cmd":"read","file":"main.go"}
    ```

    <Tip>
      The converter uses a stateful parser that tracks context (inside/outside string) to avoid incorrect substitutions.
    </Tip>
  </Accordion>

  <Accordion title="3. Unquoted Keys" icon="key">
    Adds double quotes to keys that are not quoted. Uses regex to detect the `{key:` or `, key:` pattern.

    ```
    Input:  {cmd: "read", file: "main.go"}
    Output: {"cmd": "read", "file": "main.go"}
    ```
  </Accordion>

  <Accordion title="4. Combined: Quotes + Keys" icon="layer-group">
    Applies the single quote fix first, then the unquoted keys fix. Resolves cases where both problems coexist.

    ```
    Input:  {cmd: 'read', file: 'main.go'}
    Output: {"cmd": "read", "file": "main.go"}
    ```
  </Accordion>

  <Accordion title="5. Trailing Commas" icon="comma">
    Removes commas before `}` or `]` that make the JSON invalid.

    ```
    Input:  {"cmd":"read","file":"main.go",}
    Output: {"cmd":"read","file":"main.go"}
    ```
  </Accordion>

  <Accordion title="6. Plain String Wrapping" icon="box">
    When the model sends only a raw value instead of a JSON object, the system wraps it in the correct field based on the tool name.

    ```
    Tool: read_file    Input: main.go     => {"file":"main.go"}
    Tool: run_command  Input: ls -la      => {"cmd":"ls -la"}
    Tool: search_files Input: TODO        => {"term":"TODO"}
    ```

    The mapping covers 30+ tools and aliases, including native functions (`read_file`, `write_file`) and coder subcommands (`read`, `exec`, `search`).
  </Accordion>

  <Accordion title="7. Aggressive Object Literal Fix" icon="hammer">
    For object literals with no quotes at all, the system manually parses `key: value` pairs and rebuilds valid JSON.

    ```
    Input:  {cmd: read, file: main.go, append: true}
    Output: {"cmd":"read","file":"main.go","append":true}
    ```

    Values are interpreted intelligently:

    * `true`/`false` -> booleans
    * Numbers -> JSON numbers
    * `null`/`none` -> null
    * Quoted strings -> strings (quotes removed)
    * Everything else -> string
  </Accordion>
</AccordionGroup>

***

## Tool-to-Field Mapping

Plain string wrapping uses an extensive mapping of tool names to their primary input field:

<Tabs>
  <Tab title="Native Tools">
    | Tool             | Field  | Example                                 |
    | :--------------- | :----- | :-------------------------------------- |
    | `read_file`      | `file` | `main.go` -> `{"file":"main.go"}`       |
    | `write_file`     | `file` | `output.txt` -> `{"file":"output.txt"}` |
    | `list_directory` | `dir`  | `./src` -> `{"dir":"./src"}`            |
    | `search_files`   | `term` | `TODO` -> `{"term":"TODO"}`             |
    | `run_command`    | `cmd`  | `go build` -> `{"cmd":"go build"}`      |
    | `run_tests`      | `dir`  | `./pkg` -> `{"dir":"./pkg"}`            |
  </Tab>

  <Tab title="Coder Subcommands">
    | Subcommand | Field  | Example                                   |
    | :--------- | :----- | :---------------------------------------- |
    | `read`     | `file` | `config.yaml` -> `{"file":"config.yaml"}` |
    | `write`    | `file` | `data.json` -> `{"file":"data.json"}`     |
    | `exec`     | `cmd`  | `make test` -> `{"cmd":"make test"}`      |
    | `search`   | `term` | `func main` -> `{"term":"func main"}`     |
    | `tree`     | `dir`  | `./internal` -> `{"dir":"./internal"}`    |
  </Tab>

  <Tab title="Generic Aliases">
    | Alias            | Field       |
    | :--------------- | :---------- |
    | `bash` / `shell` | `command`   |
    | `Bash`           | `command`   |
    | `Read` / `Write` | `file_path` |
    | `Glob` / `Grep`  | `pattern`   |
    | `Edit`           | `file_path` |
  </Tab>
</Tabs>

<Note>
  Wrapping is only applied when the value does **not** look like CLI arguments (no `--flags`) and does **not** start with `{` or `[`. This avoids conflicts with the existing CLI argument parser.
</Note>

***

## Unicode Quote Normalization

In addition to JSON recovery, ChatCLI normalizes curly (Unicode) quotes to straight (ASCII) quotes automatically. LLMs frequently generate typographic quotes that cause compilation errors:

| Character | Unicode               | Replacement                 |
| :-------- | :-------------------- | :-------------------------- |
| `'` `'`   | U+2018, U+2019        | `'` (straight single quote) |
| `"` `"`   | U+201C, U+201D        | `"` (straight double quote) |
| `'`       | U+2032 (prime)        | `'`                         |
| `"`       | U+2033 (double prime) | `"`                         |
| `<<` `>>` | U+00AB, U+00BB        | `<<` `>>`                   |

Normalization is applied automatically to **code files** (60+ recognized extensions) and **always** to tool call arguments.

***

## Configuration

The recovery system works automatically without configuration. All strategies are applied in order until one produces valid JSON.

| Variable | Description                                          | Default       |
| :------- | :--------------------------------------------------- | :------------ |
| *(none)* | JSON recovery has no dedicated environment variables | Always active |

<Info>
  The recovery strategies are **non-destructive**: if none produces valid JSON, the original text is passed through so the CLI parser can attempt to interpret it as positional arguments.
</Info>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Plugin @coder" icon="hammer" href="/features/coder-plugin">
    Complete reference for the tools that use JSON recovery.
  </Card>

  <Card title="Native Tool Use" icon="wrench" href="/features/native-tool-use">
    With native tool use, JSON comes validated by the API -- less need for recovery.
  </Card>

  <Card title="Tool Result Management" icon="database" href="/features/tool-result-management">
    How tool results are managed after execution.
  </Card>

  <Card title="Coder Mode" icon="code" href="/core-concepts/coder-mode">
    The complete engineering workflow with tool calls.
  </Card>
</CardGroup>
