Repository navigation
OpenAI-compatible models can call write/edit with invalid schema arguments #29142
Description
Description
OpenCode intermittently invokes built-in write and edit tools with invalid argument shapes when using OpenAI-compatible models. The UI surfaces schema errors instead of recovering or prompting the model with the exact expected schema.
This causes repeated failed tool calls and can trap an agent in a loop. I have seen it with local Qwen via LM Studio, and a similar planner flow with DeepSeek V4 Flash Free when the prompt asked the model to create a task packet file.
Related/possibly duplicate issues:
- The write tool was called with invalid arguments: SchemaError #24604 reports
writewithSchemaError(Missing key at ["content"]) - Loss of File Modification Capability for Complex Scripts #24620 reports broader file modification failures
- Write tool called with invalid parameters #18131 was suggested by the duplicate bot on The write tool was called with invalid arguments: SchemaError #24604
This report adds concrete edit failures as well as write failures on OpenCode 1.15.10.
OpenCode version
opencode version: 1.15.10
os: Darwin 25.5.0 arm64
terminal: dumb
plugins: none
Installed as the macOS desktop app / CLI.
Model/provider setup
Observed primarily with:
qwen3-coder-next/qwen3-coder-next- OpenAI-compatible provider pointed at LM Studio,
http://127.0.0.1:1234/v1
Also observed in a planner workflow using:
opencode/deepseek-v4-flash-free
Symptoms
Write tool failure
From captured output:
✗ Write requirements.txt failed
Error: The write tool was called with invalid arguments: SchemaError(Missing key
at ["content"]).
Please rewrite the input so it satisfies the expected schema.
Another captured run:
Error: The write tool was called with invalid arguments: SchemaError(Missing key
at ["content"]).
Please rewrite the input so it satisfies the expected schema.
The model appeared to send a write call using a non-matching key such as fileContent rather than the expected content key.
Edit tool failure
From captured output:
✗ Edit failed
Error: The edit tool was called with invalid arguments: SchemaError(Missing key
at ["filePath"]).
Please rewrite the input so it satisfies the expected schema.
This repeated many times in one session. In the same run, valid-looking edit attempts also sometimes failed with normal semantic errors such as multiple oldString matches, then subsequent attempts lost the filePath entirely and hit schema validation.
Steps to reproduce
One reliable pattern for me:
- Configure an OpenAI-compatible local model in OpenCode, e.g. LM Studio serving Qwen Coder.
- Run
opencode runwith a coding task that requires creating or editing files. - Ask the agent to create or modify files using OpenCode's normal write/edit tools.
- Observe
writeoredittool calls fail schema validation before execution.
Example command shape:
opencode run \
--dir /path/to/repo \
--agent qwen \
--model qwen3-coder-next/qwen3-coder-next \
"Read a local task packet and implement the listed files."The issue appears more likely with local/OpenAI-compatible models, but the failure is surfaced by OpenCode's tool schema handling.
Expected behavior
OpenCode should either:
- expose tool schemas to models in a way that reliably causes correct keys (
content,filePath, etc.), or - repair/reject malformed tool calls with a clear model-visible correction, or
- include enough diagnostics to show the malformed tool-call payload safely.
At minimum, if the model sends fileContent for write, it would be helpful to either accept common aliases or return a tool error that explicitly says write requires { filePath, content }.
Actual behavior
OpenCode displays:
The write tool was called with invalid arguments: SchemaError(Missing key at ["content"])
and/or:
The edit tool was called with invalid arguments: SchemaError(Missing key at ["filePath"])
The agent often retries and accumulates many failed tool calls. I had to work around it by disabling edit/write for local agents and making the harness write files itself from final chat output, or forcing shell heredocs.
Workaround used locally
Project agent config now denies the problematic tools:
permission:
read: allow
glob: allow
grep: allow
list: allow
bash: allow
edit: deny
write: denyFor planner flows, I changed prompts so the model returns markdown between markers, then an external shell harness writes the file. For implementer flows, I force shell heredocs instead of OpenCode write / edit.
This works around the issue, but it removes one of OpenCode's core file-editing paths for local models.
Activity
nikhilkulkarni1755 commentedon Jun 1, 2026
PR open at #30224.
github-actions commentedon Aug 1, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
VrilLabs commentedon Aug 23, 2026
For anyone landing here from a search: there are two different causes behind this same
SchemaError(Missing key ...)message, and they need different fixes. Worth checking which one you actually have before trying anything, because the fix for the second one isn't a plugin.Look at the recorded tool input for a failed call:
{"fileContent": "...", "path": "..."}{}— emptylimitconfig1. Mis-keyed arguments
This is the case in the original report — the model sends the right values under the wrong names (
fileContentforcontent,pathforfilePath). The error names the missing key but never says what the model should have sent, so it retries the same shape and loops.This can be fixed from userland with no rebuild, because
tool.execute.beforeruns before the schema decode and receives the live args object (insession/tools.ts,plugin.trigger("tool.execute.before", …)precedesitem.execute). Renaming the key in place there makes the call succeed rather than just producing a better error.Plugin doing that, plus reordering the
writeschema sofilePathis declared beforecontent: https://github.com/VRIL-LABS/better-write-opencode — MIT, drop one file into~/.config/opencode/plugins/.2. Empty
{}arguments — this one is a config issueIf the failing input is an empty object, there are no keys to rename and no plugin can help. The model degenerated and emitted a tool call with no arguments.
In my case this traced back to auto-compaction never running. Custom providers default to
limit.context = 0, andisOverflow()insession/overflow.tsreturns early on exactly that:So with a custom
@ai-sdk/openai-compatibleprovider that doesn't declare limits, compaction never fires, context grows unbounded, and the model eventually emits argument-less tool calls. Measured over one session: tool calls succeeded at ~66k input tokens on average, and failed from ~80k all the way up to 167k. Every single failure hadinput = {}— 70bash, 18write.The fix is to declare limits on the model:
limit.inputis the useful knob here —usable = limit.input − reserved, so you can declare the true context window while still compacting early enough to stay in the range where the model reliably emits well-formed tool calls.Either way, none of this requires
edit: deny/write: deny. Hope it saves someone the same detour.