Repository navigation
Description
Summary
The OpenCode Go ("Console Go") OpenAI-compatible chat completions endpoint rejects any request containing a standard OpenAI image_url content part with HTTP 400 and a raw serde deserialization error — even for models whose actual upstream API (e.g. DeepSeek official API) tolerates images ("unsupported but does not error"). This breaks third-party OpenAI-compatible clients that send images inline (in my case: Codex CLI in responses wire mode → CLIProxyAPI v7.2.120 in OpenAI-compat mode → Console Go /chat/completions).
Error returned
{"error":{"param":null,"type":"invalid_request_error","code":"invalid_request_error","message":"Error from provider (Console Go): Upstream request failed: [invalid_request_error]\nFailed to deserialize the JSON body into the target type: messages[3]: unknown variant `image_url`, expected `text` at line 1 column 76497"}}Steps to reproduce
Send a standard OpenAI chat completions request with an image content part to the Console Go endpoint (model deepseek-v4-flash):
{
"model": "deepseek-v4-flash",
"messages": [
{"role": "system", "content": "You are a coding agent."},
{"role": "user", "content": "hello"},
{"role": "assistant", "content": "hi"},
{"role": "user", "content": [
{"type": "text", "text": "what is this?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."}}
]}
],
"stream": true
}Result: HTTP 400 with the serde error above. The identical request with only text content succeeds. The failure is in the request schema, before the model is reached (the error echoes the request body and points at messages[3]).
Why opencode CLI itself never hits this
In opencode CLI, pasted images are stored as file attachments in the session and are not sent inline to the model — the model reads them via tools (e.g. the modlens skill). So the Console Go endpoint is effectively only ever exercised with image_url content parts by third-party OpenAI-compatible clients, which is why this looks fine in the opencode TUI.
Expected behavior
- Accept standard
image_urlcontent parts (pass through, or ignore like the DeepSeek official API does per its docs), OR - Return a proper OpenAI-style error envelope instead of echoing a serde error that includes the request body, OR
- At minimum do not reject the entire request because one message contains an image part.
Environment
- OpenCode version: latest (1.18.x line), issue filed 2026-08-06
- Endpoint: Console Go OpenAI-compatible endpoint (opencode-go plan), model
deepseek-v4-flash - Client path: Codex CLI (
wire_api = "responses") → CLIProxyAPI v7.2.120 (openai-compat) → Console Go/chat/completions
Related issues
- OpenAI-compatible providers: image_url content type fails deserialization when sending images #26106 — same
unknown variant 'image_url', expected 'text'serde error (closed as duplicate-spam; underlying issue appears unfixed) - VS Code extension: pasted images break multi-turn chat with 400 invalid_request_error (content sent as image_url array instead of string) #31870 — opencode-go +
kimi-k2.6,image_urlarray on a history message rejected with 400 - [OpenCode Go] 多模态模型全部无法接收图片 — HTTP 500 Internal Server Error #33942 — OpenCode Go chat completions image input returns HTTP 500 (same feature gap, different failure mode)
- Error from provider (Console Go): Upstream request failed #37231 / OpenCode Go: kimi-k3, kimi-k2.6, kimi-k2.7-code, glm-5.2, grok-4.5, qwen3.7-max, hy3-preview all fail with 'Upstream request failed' — non-standard 'mcp'/'system' fields rejected by strict provider validators #37771 — Console Go "Upstream request failed" caused by strict provider validators
Activity
github-actions commentedon Aug 6, 2026
This issue might be a duplicate of existing open issues. Please check:
If your issue is distinct (e.g. specific to the third-party OpenAI-compatible client path through the Console Go endpoint rather than the VS Code extension), please add a note clarifying the difference so it can be tracked separately.
lookvincent commentedon Aug 6, 2026
Thanks for the triage. This issue is distinct from #31870 and #33942, so a clarifying note:
Scope: this is specifically the third-party OpenAI-compatible client path: Codex CLI (Responses wire) → CLIProxyAPI (OpenAI-compat mode) → Console Go
/chat/completions. It is not the VS Code extension (#31870) and not the zen/go 500 path (#33942).Distinct failure mode: a standard OpenAI chat completions request with
image_urlcontent parts is rejected with HTTP 400 before reaching the model, via strict serde deserialization:This is a request-schema rejection (the error echoes the request body), not an upstream model error, and not a 500.
Why this is effectively the only way to hit it: opencode CLI stores pasted images as file attachments in the session and never sends
image_urlinline — the model reads them via tools (e.g. themodlensskill). So the Console Go endpoint'simage_urlhandling can only be exercised by third-party OpenAI-compatible clients, which is exactly this case. The actual upstream model API (DeepSeek official) tolerates image parts ("unsupported but does not error" per its docs), so the rejection is entirely at the Console Go gateway schema layer.Minimal ask: either accept/ignore standard
image_urlcontent parts (matching upstream model behavior), or at minimum return a proper OpenAI-style error envelope instead of a serde error that echoes the request body, so third-party clients can degrade gracefully instead of failing every request that contains an image (including retries that replay the conversation history).github-actions commentedon Oct 7, 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.