Skip to content

Engine: a tool call truncated at the provider's output limit is repaired into valid JSON and executed #5986

Description

@Hmbown

What happens

A tool call cut off by the provider's output limit can be silently completed into valid JSON and executed. For a write, the user's file is overwritten with a partial body while the model was still mid-argument.

Root cause

crates/tui/src/tools/arg_repair.rs runs a five-stage repair ladder and returns Ok(value) identically regardless of which stage succeeded. Stages 1-3 (strict parse, control-char stripping, trailing commas) normalize text that was already structurally complete. Stage 4 balance_braces (arg_repair.rs:114-132) invents structure — and it counts {/} without tracking string literals, so a stream cut right after a complete string value needs exactly one appended } to parse.

The caller therefore cannot distinguish "the model finished writing this" from "we guessed the ending". input_parse_error stays None and dispatch sees a well-formed argument.

output_limit_truncated does exist (crates/tui/src/core/engine/turn_loop.rs:1553) but is first read at :1888 and :2528after dispatch at :2648 — and the truncation notice is appended to the session after the tool result. Nothing on the dispatch path consults it.

Reproduction

Argument text {"path": "notes.md", "content": "first line" (stream cut after a complete string value) parses to {"path": "notes.md", "content": "first line"} and dispatches. notes.md is written containing only first line.

Why this matters

AGENTS.md lists data-loss handling as never-cut. There is no test covering it — grep "output limit\|max_tokens" crates/tui/src/core/engine/tests.rs finds nothing.

Found by

Comparing against refs/piagent, whose agent loop branches on stopReason === "length" before executing anything, with a comment naming this exact defect class. Recorded in codewhale-ops/FINDINGS-20260907-REFS-STUDY-AND-DEFECTS.md §1.1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions