Repository navigation
Description
Summary
opencode v2 (beta) unconditionally sends prompt_cache_key in Chat Completions requests to all OpenAI-compatible providers. Gateways that strictly validate request fields (e.g. third-party relay/relay-style APIs) reject the request with HTTP 400 (未知请求字段:prompt_cache_key / unknown request field), making every session fail. Additionally, the documented setCacheKey provider option ("Enable promptCacheKey for this provider (default false)") has no runtime effect in v2 — it appears only in the config schema, so there is no way to opt out.
opencode 1.x does not have this problem: it only sets promptCacheKey for specific provider packages (@ai-sdk/deepinfra, @ai-sdk/cerebras, @ai-sdk/openai, @ai-sdk/azure, @ai-sdk/xai, @ai-sdk/mistral, venice-ai-sdk-provider), or when setCacheKey: true is explicitly set. Providers using @ai-sdk/openai-compatible are not affected.
Environment
- opencode version:
opencode2 v0.0.0-beta-18230(broken) vsopencode 1.18.23(works) - OS: Linux 6.18.33.2-microsoft-standard-WSL2 (x64)
- Terminal: tmux (TERM=xterm-256color)
- Shell: zsh
- Install/channel: npm
@opencode-ai/cli(beta) - Active plugins: opencode-workspace-scope@0.1.1
Reproduction
- Configure a custom provider in
~/.config/opencode/opencode.jsoncusing"npm": "@ai-sdk/openai-compatible"pointing at an OpenAI-compatible gateway that strictly validates fields (in my case a third-party relay service). - Set
"setCacheKey": falsein the provider'soptions. - Start any session with one of its models.
The gateway receives a request body containing "prompt_cache_key": "<session-id>" and responds:
HTTP 400
{"code":"UNKNOWN_FIELD","message":"未知请求字段:prompt_cache_key","data":{"field":"prompt_cache_key"}}
Minimal curl proof that the field itself triggers the rejection against this gateway:
# rejected
curl https://<gateway>/v1/chat/completions -d '{"model":"...","messages":[{"role":"user","content":"hi"}],"max_tokens":5,"prompt_cache_key":"test"}'
# → {"code":"UNKNOWN_FIELD","message":"未知请求字段:prompt_cache_key"}
# works
curl https://<gateway>/v1/chat/completions -d '{"model":"...","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'
# → normal completionSource analysis on the v2 branch:
- The key is attached unconditionally to every session request —
packages/core/src/session/model-request.ts:331:// TODO: Persist cache lineage so nested forks reuse the root session's cache key. promptCacheKey: promptCacheKey(session.fork?.sessionID ?? session.id),
- Every OpenAI-chat-compatible route (including custom
openai-compatibleproviders) lowers it to the wire field —packages/ai/src/protocols/openai-chat.ts:702:...(cacheKey ? { prompt_cache_key: cacheKey } : {}),
- The only opt-out is
request.cache === "none"—packages/ai/src/protocols/shared.ts:32. Nothing in core ever sets it; only tests do. Notablyopenai-chat.tsalready special-cases non-standard providers forstore("Non-standard providers omitstoreentirely", line ~701) but not forprompt_cache_key. setCacheKeyhas zero consumers on the v2 branch: it appears only in the v1 compat schema (packages/core/src/v1/config/provider.ts:93) and in docs (config.mdx). The per-provider gating logic that v1 had was lost during the request-construction refactors (refactor(core): share session model requests #42680, refactor(core): fold single-consumer request modules into model-request #43958).
Expected Behavior
setCacheKey: falsein provider options should suppressprompt_cache_key(the option is still documented in the schema), or be removed from the schema if intentionally dropped. Minimal fix: honor the provider option atmodel-request.ts:331by omittingpromptCacheKey(or mapping tocache: "none").- Ideally,
prompt_cache_keyshould not be sent to genericopenai-compatibleproviders by default (matching v1 behavior), since it is an OpenAI-specific extension that many compatible gateways reject.
Actual Behavior
Every request to the provider fails with HTTP 400 UNKNOWN_FIELD: prompt_cache_key. No configuration can disable it in v2, so affected providers are completely unusable.
Log excerpt:
level=ERROR message="Failed to drain Session"
cause="AI.Error: RequestExecutor.execute: Provider request failed with HTTP 400: 未知请求字段:prompt_cache_key"
Additional Context
- Frequency: 100% reproducible with the affected provider on every v2 release I tested; 0% on opencode 1.18.23 with identical config.
- Current workaround: none within v2 (config option is inert). Rolling back to opencode 1.x restores access.
- Related issues: setCacheKey sends promptCacheKey (wrong) instead of cache_control on content blocks for openai-compatible Bedrock proxies (Bifrost, LiteLLM) #25984 (setCacheKey sends the wrong cache format for openai-compatible Bedrock proxies), V2 drops prompt cache affinity for OpenRouter and OpenAI Chat #42246 (V2 drops prompt cache affinity for OpenRouter/OpenAI Chat) — together these suggest the v2 request-construction rewrite lost v1's per-provider cache-key gating in both directions. Same failure class has been reported against other gateways, e.g. strict relays rejecting
prompt_cache_keywith HTTP 400. - Suggestion for other gateway vendors would be to ignore unknown fields like the official OpenAI API does, but opencode should honor its own documented opt-out regardless.
Activity
max88578smith commentedon Sep 3, 2026
@gnh1996 strip-cache-key__plugin_v2.zip
Same issue: This seems to help me in the meantime
piknockyou commentedon Sep 11, 2026
Yes. Nvidia NIM doesn't work now, right?
simplestringdev commentedon Sep 11, 2026
Confirming this also reproduces against NVIDIA's own official OpenAI-compatible endpoint (
https://integrate.api.nvidia.com/v1), not just third-party relays — so this isn't limited to strict/unusual gateways, it breaks against a major vendor's first-party API.Setup:
opencode runfails immediately:Direct curl against the same endpoint with
prompt_cache_keyomitted works fine, confirming the field itself is the problem, same as OP's analysis.setCacheKey: false(and removing the option entirely) had no effect either way — consistent with the "zero consumers on v2" finding above.Version:
opencode2 v0.0.0-beta-19425, Linux x64.Workaround for now: using the built-in
opencode/nemotron-3-ultra-free(OpenCode Zen) model instead of a custom NVIDIA provider, since Zen models aren't affected.rekram1-node commentedon Oct 5, 2026
#49121 (#49121)
Any version 2.0.4 or later has fix.
FunStudio commentedon Nov 1, 2026