Error from provider (Console Go): Upstream request failed - cc-switch
Quick fix
Check whether the model mapping was applied. If the target model is unavailable or the request body contains an unsupported tool_choice or image… (cc-switch)
Symptom
Section titled “Symptom”{"error":{"param":null,"code":"invalid_request_error","type":"invalid_request_error","message":"Error from provider (Console Go): Upstream request failed: [invalid_request_error] Thinking mode does not support this tool_choice"}}This is a generic upstream failure returned by the OpenCode Go (Console Go) gateway. When it occurs in the local cc-switch proxy chain, it can have several causes. First, model mapping may be silently skipped: after skills are re-imported, the proxy reloads its internal state and loses session context, so the original model name (such as `claude-sonnet-4-6`) is passed directly upstream, which cannot recognize it and returns 400 (#5312). Second, `tool_choice` or tool definitions in the request body may fail strict upstream validation: Claude Code’s built-in WebSearch forces an Anthropic-style `server_tool`, while the upstream accepts only `auto` or `{"type":"web_search"}` (#6367); when Codex passes native Responses requests through, grok-* models return 422 for `custom`, `tool_search`, or function tools with missing `parameters` (#7138). Third, declared model capabilities may not match the gateway’s actual capabilities: DeepSeek declares image support, but the Console Go gateway recognizes only `text` content blocks, so pasting an image returns 400 (#6450). Fourth, a failover target model may have been discontinued. cc-switch’s `categorize_proxy_error()` classifies all such 400 errors as NonRetryable, so it neither trips the circuit breaker nor fails over, and requests continue to fail (#6821).
Check the local proxy version. The issue where re-importing skills caused mapping loss was fixed after the local routing takeover was rewritten in version 4.0. Upgrade to the latest cc-switch, re-import the skills, and verify.
If the error contains 'Thinking mode does not support this tool_choice', check the model mapping configuration. Ensure `claude-*` model names map to a model the upstream actually supports, such as `deepseek-v4-flash`, rather than passing the original name through directly.
If a mapped model in the failover queue has been discontinued, such as `deepseek-v4-flash-free`, change that provider’s model mapping to an available model name, such as `hy3-free`, or remove the provider from the queue.
If pasting an image immediately returns 400, the current chain does not support `image_url` content blocks. Avoid pasting images directly into Claude Code, use a vision-capable provider or protocol, or wait for the Vision Proxy feature.
If Codex returns 422 when using a grok-* model through OpenCode Zen Go, there is currently no configuration-level fix. Wait for cc-switch to extend the sanitize gate, or add a conversion layer between the client and proxy.
Affected Versions
Section titled “Affected Versions”Source Issues
Section titled “Source Issues”This page is distilled from 5 real issues
- #5312Model name mapping silently dropped after skill re-import, causing 400 errors from upstream
- #6367[Bug] Claude Code 内置 WebSearch 经 DeepSeek(OpenCode Go) Responses 路由时报 400: Thinking mode does not support this tool_choice
- #6450[Feature] Vision Proxy:图片自动注入视觉描述,且注入开关需独立于模型能力声明(附代码定位)
- #6821[Bug] 上游 400 "Model is unavailable"(failover 目标模型已下线)被归为 NonRetryable:不熔断、不转移,分类器请求反复挂起 / Upstream 400 for dead failover target model treated as NonRetryable — no circuit breaker, no failover
- #7138Codex 原生 Responses 透传遇严格第三方 Responses 网关(OpenCode Zen Go)时 422:清洗器 gate 限于 xai_oauth,且 tools 转换缺失
- Why does Claude Code suddenly return 400 for everything after I re-import skills?
- This is a known issue in cc-switch 3.16.5: re-importing skills reloads the proxy’s internal state and clears the association between sessions and providers. Model mapping is then silently skipped, and the original model name is passed directly upstream. Version 4.0 rewrote local routing takeover; upgrade and verify.
- Why does WebSearch produce Thinking mode does not support this tool_choice, while ordinary conversations work?
- Claude Code’s built-in WebSearch forces an Anthropic-style `server_tool` tool_choice, while the upstream DeepSeek Responses API accepts only `auto` or `{"type":"web_search"}`. The cc-switch translation layer does not adapt this, so wait for a fix.
- Why does pasting an image return 400 even though the model declares image support?
- A declared model capability, such as DeepSeek image support, does not guarantee that the forwarding gateway supports it. The Console Go gateway recognizes only `text` content blocks and rejects `image_url` during serde deserialization. Because the capability check marks it Supported, cc-switch’s media_sanitizer skips stripping the image and forwards it unchanged.
- Why doesn’t an upstream 400 saying Model is unavailable automatically switch to the next provider?
- cc-switch’s `categorize_proxy_error()` classifies every 400 as NonRetryable, so it does not trip the circuit breaker or trigger failover. Even when the response body clearly says the model has been discontinued, the unavailable provider is not skipped automatically. Manually adjust the failover queue or wait for the classifier to improve.
Related problems
Section titled “Related problems”This is an unofficial community wiki with no affiliation to the cc-switch authors or the project itself. Its content is compiled from the project's public GitHub issues. This site distributes no software.