fix(tool): coerce object arguments to string in edit and write tools#21713
fix(tool): coerce object arguments to string in edit and write tools#21713extrasmall0 wants to merge 1 commit intoanomalyco:devfrom
Conversation
Some models (Qwen3-Coder, GLM4.7, and others) occasionally emit a JSON object rather than a plain string for tool parameters that expect strings — e.g. oldString / newString in the edit tool or content in the write tool. Zod rejects these outright, producing a hard validation error that causes the model to loop. Add a z.preprocess step on each affected parameter that serialises any incoming object value (via JSON.stringify) so it becomes a valid string before zod validates it. Plain string inputs are unchanged. Also reorder write tool parameters so filePath comes before content, matching the edit, read, and apply_patch tools. Small/quantised models are sensitive to property order in JSON schemas and more reliably emit filePath when it appears first. Fixes anomalyco#6918
|
The following comment was made by an LLM, it may be inaccurate: Found potential related PRs:
These PRs appear to address the same or overlapping issues from this PR. PR #14744 and #14832 may have been previous attempts or partial fixes for the problems this PR comprehensively addresses. |
|
The Windows e2e failure appears to be a pre-existing flaky environment issue — I can see it also fails on recently merged PRs (e.g. #21803) that have no relation to this change. All other checks pass (unit Windows/Linux, typecheck, lint). Happy to rebase or add more context if needed. |
Issue for this PR
Closes #6918
Type of change
What does this PR do?
Several models (Qwen3-Coder, GLM4.7, Gemini-3-pro-preview, and others) occasionally emit a JSON object rather than a plain string for tool parameters that are supposed to be strings — e.g.
oldString/newStringin theedittool orcontentin thewritetool. Zod rejects these outright with:This causes the model to loop on the same error indefinitely.
Fix: Add a
z.preprocessstep on each affected parameter that serialises any incoming object value viaJSON.stringifybefore Zod validates it. Plain string inputs pass through unchanged.Additionally, reorder the
writetool parameters sofilePathcomes beforecontent, matchingedit,read, andapply_patch. Small/quantised models are sensitive to JSON schema property ordering and reliably emitfilePathwhen it appears first — this also addresses thereceived undefinedvariant of the write-tool error.How did you verify your code works?
bun test packages/opencode/test/tool/edit.test.ts— all pass.Checklist