Skip to content

fix(tool): coerce object arguments to string in edit and write tools#21713

Open
extrasmall0 wants to merge 1 commit intoanomalyco:devfrom
extrasmall0:fix/edit-write-coerce-object-args
Open

fix(tool): coerce object arguments to string in edit and write tools#21713
extrasmall0 wants to merge 1 commit intoanomalyco:devfrom
extrasmall0:fix/edit-write-coerce-object-args

Conversation

@extrasmall0
Copy link
Copy Markdown

Issue for this PR

Closes #6918

Type of change

  • Bug fix

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 / newString in the edit tool or content in the write tool. Zod rejects these outright with:

Error: The edit tool was called with invalid arguments: [
  { "expected": "string", "code": "invalid_type", "path": ["oldString"], "message": "Invalid input: expected string, received object" }
]

This causes the model to loop on the same error indefinitely.

Fix: Add a z.preprocess step on each affected parameter that serialises any incoming object value via JSON.stringify before Zod validates it. Plain string inputs pass through unchanged.

Additionally, reorder the write tool parameters so filePath comes before content, matching edit, read, and apply_patch. Small/quantised models are sensitive to JSON schema property ordering and reliably emit filePath when it appears first — this also addresses the received undefined variant of the write-tool error.

How did you verify your code works?

  • Ran existing tests: bun test packages/opencode/test/tool/edit.test.ts — all pass.
  • The object-input path can only be triggered by a live misbehaving model; the preprocess logic is straightforward enough that a code review should be sufficient.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

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
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

The following comment was made by an LLM, it may be inaccurate:

Found potential related PRs:

  1. PR fix: put filePath before content in write tool schema #14744 - "fix: put filePath before content in write tool schema"

    • Addresses the parameter ordering issue mentioned in this PR (filePath before content in write tool)
  2. PR fix(opencode): write.ts coerce JSON objects to strings #14832 - "fix(opencode): write.ts coerce JSON objects to strings"

    • Directly related to the same issue of coercing JSON objects to strings in the write tool

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.

@github-actions github-actions bot mentioned this pull request Apr 9, 2026
6 tasks
@extrasmall0
Copy link
Copy Markdown
Author

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.

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.

qwen3-coder fails to call edit tool

1 participant