Skip to content

fix: repair malformed JSON in edit_file tool call arguments#2452

Merged
dgageot merged 1 commit intodocker:mainfrom
trungutt:fix/edit-file-malformed-json
Apr 17, 2026
Merged

fix: repair malformed JSON in edit_file tool call arguments#2452
dgageot merged 1 commit intodocker:mainfrom
trungutt:fix/edit-file-malformed-json

Conversation

@trungutt
Copy link
Copy Markdown
Contributor

Summary

LLMs sometimes generate broken JSON when calling edit_file. This happens because the text being edited (YAML files, Dockerfiles, shell scripts) contains braces, brackets, and escape characters that throw off the model's nesting depth tracking. The result is structurally invalid JSON that fails to parse, wasting a turn and forcing the model to retry.

I looked at all edit_file calls across several sessions and found that 11 out of 53 calls (21%) had malformed arguments. All of them were close to valid — typically just one extra } or ] in the wrong place.

The existing UnmarshalJSON fix for double-serialized edits (#2144) doesn't help here because Go's json.Unmarshal scanner rejects the structurally invalid JSON before any custom unmarshaler runs.

What this PR does

Adds tryRepairEditFileJSON which, on a json.SyntaxError, looks at the character at the error offset and removes it if it's a known garbage pattern. It loops up to 3 times to handle multiple issues in the same payload. The observed failure patterns from real sessions:

Pattern Count Example Repair
Extra } 8 "}}]} instead of "}]} Remove the extra }
Extra ] 2 "}]]} instead of "}]} Remove the extra ]
Stray \n between tokens 1 "}\n]} Remove both \ and n
Stray \ before " 1 {\"key" instead of {"key" Remove the \

Since the repair needs to happen before json.Unmarshal, the edit_file handler now uses a custom editFileHandler() instead of the generic tools.NewHandler, calling the new exported ParseEditFileArgs function directly. All other call sites (ACP filesystem handler, TUI rendering) are updated to use ParseEditFileArgs too.

What it doesn't do

  • No generic JSON repair for all tools — this is scoped to edit_file only, where the problem is most acute due to large text payloads
  • No changes to the streaming/accumulation path
  • Unrepairable garbage (e.g. {totally broken <<<>>>) still fails with a clear error

@trungutt trungutt force-pushed the fix/edit-file-malformed-json branch from 95c18e5 to 5b289dd Compare April 16, 2026 16:10
LLMs occasionally generate structurally invalid JSON for edit_file
arguments when the text payload contains characters that confuse brace
counting (YAML, Dockerfiles, shell scripts). The most common pattern is
an extra closing brace or bracket near the end of the arguments.

Go's json.Unmarshal scanner rejects this before any custom UnmarshalJSON
method runs, so the existing double-serialization fix never fires for
these cases.

Add tryRepairEditFileJSON which iteratively removes the offending
character at the json.SyntaxError offset (up to 3 rounds), handling
extra }, extra ], stray backslash-n, and stray backslash before quotes.

Replace NewHandler with a custom editFileHandler that calls
ParseEditFileArgs (which does repair then unmarshal) before delegating
to handleEditFile. Update all other call sites (ACP filesystem handler,
TUI rendering) to use ParseEditFileArgs as well.
@trungutt trungutt force-pushed the fix/edit-file-malformed-json branch from 5b289dd to 092285f Compare April 16, 2026 16:12
@trungutt trungutt marked this pull request as ready for review April 16, 2026 16:13
@trungutt trungutt requested a review from a team as a code owner April 16, 2026 16:13
@dgageot dgageot merged commit 1e6975e into docker:main Apr 17, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants