You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OpenCode Go: Xiaomi MiMo rejects list-type tool message content (400 text is not set) #32613
When using OpenCode Go with Xiaomi MiMo models (e.g. mimo-v2.5), requests that include tool results with image content (e.g. browser screenshots, vision tool output) fail with a 400 error:
Error code: 400 - {"error":{"code":"400","message":"Param Incorrect","param":"`text` is not set","type":""}}
The issue is that Xiaomi MiMo API requires role: "tool" message content to be a string, but OpenAI-compatible clients send it as a list of content parts (e.g. [{"type": "text", "text": "..."}, {"type": "image_url", "image_url": {...}}]) when the tool result includes images.
OpenCode Go exposes an OpenAI-compatible /v1/chat/completions endpoint and routes MiMo requests to Xiaomi. The relay appears to pass through the list-type tool content unchanged, and Xiaomi rejects it.
Steps to Reproduce
Use OpenCode Go with mimo-v2.5 (or any MiMo model)
Send a conversation that includes a tool result with image content (e.g. from a browser/vision tool)
The tool message content is a list with text + image_url parts
Xiaomi returns 400 "text is not set"
Expected Behavior
The relay should either:
Convert list-type tool message content to a text string before forwarding to Xiaomi, or
Document that MiMo models via OpenCode Go do not support multimodal tool results
Context
This is a known Xiaomi API limitation — their API accepts multimodal user messages but rejects list-type tool message content. Other clients (Hermes Agent, OpenClaw) have hit the same issue (ref: hermes-agent#27344, openclaude#1421).
Clients can work around this by flattening tool-result images to text before sending, but since OpenCode Go positions itself as a unified OpenAI-compatible API, the relay is better positioned to handle this translation — especially since other backends behind the relay (GLM, Kimi) may handle list-type content fine, making this a per-model concern that the relay should abstract away.
Root cause: MiMo/GLM-5.2/Xiaomi require tool role messages to have content as a plain string, not ContentPart[] array. The AI SDK sends tool results as [{type: "tool-result", output: {type: "text", value: "..." }}], which these providers reject with 400 errors.
Fix: Added provider-specific transform that flattens single-part tool results to plain strings for affected providers. Multi-part content is preserved as array (providers that don't support it will error, which signals the limitation clearly.
I'm running OpenCode Go with Xiaomi MiMo v2.5 as my primary model (via Hermes Agent on a Raspberry Pi). This issue causes intermittent 400 errors whenever a tool result includes image content (vision analysis, browser screenshots, etc.), forcing fallback to non-vision models and breaking my entire image verification workflow.
What I've tried:
Routing through OpenRouter instead of OpenCode Go's native relay (works, but adds latency and loses some features)
Keeping the fallback chain as a band-aid (all fallback models lack vision, so the system becomes unusable for visual tasks)
PR #32966 by @lexlian looked like the right fix (flatten single-part tool results to plain strings for affected providers), but it was closed by automated cleanup before being reviewed. The fix was tested and passing all 277 tests.
Request: Could this be prioritized? The Xiaomi API isn't going to change this behavior — their docs explicitly require string content for tool messages. The relay is the right place to handle this translation.
Current reproduction through OpenCode Go / MiMo v2.5
I am adding current evidence to this existing issue rather than opening a duplicate.
Effective route
Hermes main commit: fe3dd9106a1c9d2327fb3795e55b09742c43bafd
Provider: opencode-go
Model: mimo-v2.5
Base URL: https://opencode.ai/zen/go/v1
Reproduction
Using a fresh temporary Hermes home, without changing the permanent configuration:
opencode-go/mimo-v2.5
→ browser_navigate completed
→ browser_vision completed
→ next request through opencode-go/mimo-v2.5
→ HTTP 400
The returned error was:
Error from provider (Xiaomi): Param Incorrect
param: `text` is not set
The request did not switch to Xiaomi as the selected Hermes provider. The effective provider remained OpenCode Go throughout the tested route. Hermes also did not silently switch to another model after the 400.
The same failure pattern was previously observed in Hermes sessions using opencode-go/mimo-v2.5 directly and after a real fallback to that route.
Question for OpenCode Go
Could you confirm how the OpenCode Go relay/adaptor maps the request state associated with browser_vision into the request sent to MiMo v2.5?
In particular:
Is a plain text field required for tool messages on this route?
Does the relay normalize list/part-based tool content before forwarding it?
Is text is not set expected for this request shape, or should the relay return a more specific compatibility response?
Scope and limitations
This is not a direct Xiaomi-provider test; the effective provider was opencode-go.
Xiaomi is mentioned only because it appears as the upstream source in the returned error.
The exact wire payload was not captured.
I am not asserting that OpenCode Go alone is the root cause; the defect may involve Hermes request construction, relay transformation, or the downstream adapter boundary.
The historical introducing change has not been identified.
A tool result that carries an image is sent as multi-part content on role: "tool": [{"type":"text","text":"..."},{"type":"image_url","image_url":{...}}]
Xiaomi rejects the request: 400, param: "text" is not set
The part worth flagging: the transform in #32966 only handles single-part tool results. It flattens a lone text/error part to a string and explicitly leaves multi-part content as an array. Multi-part is exactly the shape this bug is about, so even with that transform merged, a tool result carrying an image would still 400.
What would actually close it for these providers, either way:
hoist media out of the tool result into a normal user message — this is the existing behavior for @ai-sdk/openai-compatible in the CLI (supportsMediaInToolResult returns false for it, so the image is extracted and re-injected as a user message), and it is the same approach PR fix(opencode): hoist Bedrock tool images except Claude, Nova, and Llama 4 #50272 just merged for Bedrock; or
for role: "tool" messages specifically, emit plain-string content and move the media part to an adjacent user message.
Worth noting the asymmetry: the opencode CLI itself does not hit this, because it already hoists media out of tool results for OpenAI-compatible SDKs. It only bites clients that talk to /zen/go/v1/chat/completions directly and treat "OpenAI-compatible" literally. Since Go is advertised as an OpenAI-compatible endpoint, closing that gap on the relay side would fix every third-party client at once instead of each one shipping its own workaround.
Happy to test a fix or provide a minimal request payload if useful.
Thanks for the detailed write-up and the links to the reports in other clients!
To restate the request: when the OpenCode Go /v1/chat/completions endpoint routes to Xiaomi MiMo, you'd like the relay to flatten list-type role: "tool" message content (text + image_url parts) into a string, or at least document that MiMo does not support multimodal tool results. Without that, clients that send tool results this way get 400 "text is not set".
For context, the OpenCode app itself sends tool results to OpenAI-compatible endpoints as plain text, with any images in a separate user message, so it shouldn't hit this error. It mainly affects other clients that call the Go endpoint directly. That makes this a request for the relay to normalize content for each model, and maintainers will consider it.
Activity
lexlian commentedon Jun 19, 2026
@Cdddo @fwang , I fixed the issue with PR #32966.
Root cause: MiMo/GLM-5.2/Xiaomi require tool role messages to have
contentas a plain string, notContentPart[]array. The AI SDK sends tool results as[{type: "tool-result", output: {type: "text", value: "..." }}], which these providers reject with 400 errors.Fix: Added provider-specific transform that flattens single-part tool results to plain strings for affected providers. Multi-part content is preserved as array (providers that don't support it will error, which signals the limitation clearly.
nagdeepanjan commentedon Jul 22, 2026
+1 — still affecting OpenCode Go users
I'm running OpenCode Go with Xiaomi MiMo v2.5 as my primary model (via Hermes Agent on a Raspberry Pi). This issue causes intermittent 400 errors whenever a tool result includes image content (vision analysis, browser screenshots, etc.), forcing fallback to non-vision models and breaking my entire image verification workflow.
What I've tried:
PR #32966 by @lexlian looked like the right fix (flatten single-part tool results to plain strings for affected providers), but it was closed by automated cleanup before being reviewed. The fix was tested and passing all 277 tests.
Request: Could this be prioritized? The Xiaomi API isn't going to change this behavior — their docs explicitly require string content for tool messages. The relay is the right place to handle this translation.
Happy to help test if a new PR is opened.
Nandoca95 commentedon Jul 26, 2026
Current reproduction through OpenCode Go / MiMo v2.5
I am adding current evidence to this existing issue rather than opening a duplicate.
Effective route
maincommit:fe3dd9106a1c9d2327fb3795e55b09742c43bafdopencode-gomimo-v2.5https://opencode.ai/zen/go/v1Reproduction
Using a fresh temporary Hermes home, without changing the permanent configuration:
The returned error was:
The request did not switch to Xiaomi as the selected Hermes provider. The effective provider remained OpenCode Go throughout the tested route. Hermes also did not silently switch to another model after the 400.
The same failure pattern was previously observed in Hermes sessions using
opencode-go/mimo-v2.5directly and after a real fallback to that route.Question for OpenCode Go
Could you confirm how the OpenCode Go relay/adaptor maps the request state associated with
browser_visioninto the request sent to MiMo v2.5?In particular:
textfield required for tool messages on this route?text is not setexpected for this request shape, or should the relay return a more specific compatibility response?Scope and limitations
opencode-go.Related Hermes reproduction: NousResearch/hermes-agent#49388
fix(mimo): flatten list-type tool message content to string (upstream…
FrancoMeneses commentedon Sep 22, 2026
Adding current evidence for the third-party OpenAI-compatible client path, plus one gap that the earlier fix does not cover.
Reproduction as of today:
opencode-go, modelmimo-v2.5, base URLhttps://opencode.ai/zen/go/v1role: "tool":[{"type":"text","text":"..."},{"type":"image_url","image_url":{...}}]param: "text" is not setThe part worth flagging: the transform in #32966 only handles single-part tool results. It flattens a lone text/error part to a string and explicitly leaves multi-part content as an array. Multi-part is exactly the shape this bug is about, so even with that transform merged, a tool result carrying an image would still 400.
What would actually close it for these providers, either way:
@ai-sdk/openai-compatiblein the CLI (supportsMediaInToolResultreturns false for it, so the image is extracted and re-injected as a user message), and it is the same approach PR fix(opencode): hoist Bedrock tool images except Claude, Nova, and Llama 4 #50272 just merged for Bedrock; orrole: "tool"messages specifically, emit plain-string content and move the media part to an adjacent user message.Worth noting the asymmetry: the opencode CLI itself does not hit this, because it already hoists media out of tool results for OpenAI-compatible SDKs. It only bites clients that talk to
/zen/go/v1/chat/completionsdirectly and treat "OpenAI-compatible" literally. Since Go is advertised as an OpenAI-compatible endpoint, closing that gap on the relay side would fix every third-party client at once instead of each one shipping its own workaround.Happy to test a fix or provide a minimal request payload if useful.
opencodejr commentedon Oct 29, 2026
Thanks for the detailed write-up and the links to the reports in other clients!
To restate the request: when the OpenCode Go
/v1/chat/completionsendpoint routes to Xiaomi MiMo, you'd like the relay to flatten list-typerole: "tool"message content (text +image_urlparts) into a string, or at least document that MiMo does not support multimodal tool results. Without that, clients that send tool results this way get400 "text is not set".For context, the OpenCode app itself sends tool results to OpenAI-compatible endpoints as plain text, with any images in a separate user message, so it shouldn't hit this error. It mainly affects other clients that call the Go endpoint directly. That makes this a request for the relay to normalize content for each model, and maintainers will consider it.
Related issues:
reasoning_effortvalues)