anomalyco / anomalyco/opencode

provider: v2 always sends prompt_cache_key to OpenAI-compatible providers; setCacheKey option ignored

Open
#45,113 3 comments 2 reactions 1 assignee View on GitHub

@kitlangton is already working on this.

Since Aug 26, 2026.

2.0
Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

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) vs opencode 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

  1. Configure a custom provider in ~/.config/opencode/opencode.jsonc using "npm": "@ai-sdk/openai-compatible" pointing at an OpenAI-compatible gateway that strictly validates fields (in my case a third-party relay service).
  2. Set "setCacheKey": false in the provider's options.
  3. 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 completion

Source analysis on the v2 branch:

  1. 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),
    
  2. Every OpenAI-chat-compatible route (including custom openai-compatible providers) lowers it to the wire field — packages/ai/src/protocols/openai-chat.ts:702:
    ...(cacheKey ? { prompt_cache_key: cacheKey } : {}),
    
  3. The only opt-out is request.cache === "none"packages/ai/src/protocols/shared.ts:32. Nothing in core ever sets it; only tests do. Notably openai-chat.ts already special-cases non-standard providers for store ("Non-standard providers omit store entirely", line ~701) but not for prompt_cache_key.
  4. setCacheKey has 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 (#42680, #43958).

Expected Behavior

  1. setCacheKey: false in provider options should suppress prompt_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 at model-request.ts:331 by omitting promptCacheKey (or mapping to cache: "none").
  2. Ideally, prompt_cache_key should not be sent to generic openai-compatible providers 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: #25984 (setCacheKey sends the wrong cache format for openai-compatible Bedrock proxies), #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_key with 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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.