The request ended with an assistant message, and the gateway in front of the model refuses to continue from one. That is the whole error. It is not about your key, your balance, or the model's context window.
A request like that is called a prefill: the last message has role: "assistant", and the model is asked to keep writing it. Anthropic's own API supports it, which is why some tools rely on it. Plenty of gateways do not, and when they see a trailing assistant message they return HTTP 400 with the sentence in the title.
Two paths that end on an assistant message
Both are tracked in OpenCode's issue tracker, and both were still open on October 28, 2026.
1. An unrecognized finish reason loops the session. OpenCode stores a finish reason as one of six values; anything else becomes unknown. The run loop reads unknown as "the turn is not finished" and calls the model again without appending a user or tool message, so the array still ends with the assistant reply (#46415, opened August 31, 2026). The first report used SAP AI Core; a later comment reproduced it on Amazon Bedrock with an Anthropic model, so it is not one gateway's quirk. We reproduced the loop on OpenCode 1.18.35 with a local OpenAI-compatible endpoint: after a reply carrying finish_reason: "unknown", the next request from the CLI ended with the assistant message, and returning the 400 printed the same error in the terminal. On 2.2.0 the same harness produced a synthetic user message instead, so no trailing assistant was sent: the 400 disappeared, the extra request did not.
2. A step-capped agent sends its final instruction as an assistant message. With a steps limit, the last allowed step appends the "maximum steps reached" prompt as assistant, not user (#56250, opened October 16, 2026 against CLI 2.0.24, reported on GitLab Duo). Any gateway that forbids prefill returns the same 400 on the last step.
The error text comes from the gateway, not the model. That is why the same model can work on one endpoint and fail on another with an identical prompt.
Fixes, in the order worth trying
Raise or remove the step cap. If your agent config sets steps, the failure is deterministic: it only appears when a task needs one more tool call than the cap allows. Removing the cap, or raising it above your normal tool-call count, makes the path disappear.
Check the finish reason of the last assistant message. Text, a timestamp and finish: "unknown" point at the loop, not at your setup. Nothing in the config changes that; use a gateway that tolerates a trailing assistant message, or a version that exits on unknown (watch #46415).
If you run the gateway yourself, append a short user message when the array ends on an assistant turn. It converts the 400 into a completion; the duplicate call still happens.
Test the gateway before changing anything else. Two messages are enough:
curl -s https://your-endpoint/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"model":"your-model","messages":[
{"role":"user","content":"Say hello"},
{"role":"assistant","content":"Hello"}],"max_tokens":16}'
A 200 means the gateway accepts prefill and the 400 is coming from somewhere else. A 400 with the prefill sentence confirms it. For a control, we ran exactly this against our own endpoint on October 28, 2026 and got HTTP 200 with a length finish reason.
Sources
- OpenCode issue #46415, opened August 31, 2026, open on October 28, 2026:
https://github.com/anomalyco/opencode/issues/46415 - OpenCode issue #56250, opened October 16, 2026, open on October 28, 2026:
https://github.com/anomalyco/opencode/issues/56250 - Our own curl test against
https://api.wallabytoken.com/v1/chat/completions, October 28, 2026, HTTP 200. - Our mock-endpoint reproduction on OpenCode 1.18.35, October 28, 2026: the request following
finish_reason: "unknown"logged message rolessystem, user, assistantbefore the 400. - The same mock run on OpenCode 2.2.0, October 28, 2026: the follow-up request carried a synthetic
usermessage and no trailingassistantmessage.
Disclosure: Wallaby Token sells API access to Kimi K3. The curl control used our endpoint; the two issues are independent of it.
If you are wiring Kimi K3 into OpenCode, the catalog entry is already in the app, and the zero-config walkthrough covers the two settings that matter. Upgrading from v1? Three habits break in OpenCode 2. To try the endpoint behind the control test, wallabytoken.com gives new accounts $0.50 in trial credit, no card required.