anomalyco / anomalyco/opencode

bug(bedrock): cachePoint after reasoning block still wedges sessions on 1.18.31 — a tested fix exists in auto-closed PR #36532

Open
#49,859 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Summary

On Amazon Bedrock with Anthropic Claude (adaptive/extended thinking), when an assistant
message's last content block is a reasoning block, opencode emits the prompt-cache
breakpoint immediately after it. Bedrock rejects this:

ValidationException: Cache point cannot be inserted after reasoning block.
Please remove the invalid cache point and try again.

The failing assistant message stays in history, so every retry rebuilds the same invalid
request. The session is wedged until that message ages out of the cache window. The only
user-side escape is /undo.

Why I'm opening a new issue

Per the stale bot's own instruction on #36517 — "If the issue is still relevant please
open a new one."
It is still relevant. The history:

Date Event
2026-06-10 #31687 filed (Fable 5 on Bedrock)
2026-06-11 #31687 closed as completed against commit e2527db — but that commit is #31745 ("surface content-filter finish reason as visible error"), which does not touch cache-point placement. The bug was never fixed.
2026-07-12 #36517 filed, noting exactly that mis-attribution
2026-07-12 PR #36532 opened the same day — targeted fix, 6 regression tests, typecheck clean
2026-08-12 PR #36532 closed unmerged by automation, label automated-pr-cleanup, merged_at: null. No review comments.
2026-09-11 #36517 closed by stale bot, state_reason: not_planned

No maintainer ever evaluated the fix on merit. Two separate bots discarded first the fix,
then the report.

Environment

  • opencode 1.18.31 (current latest as of filing)
  • Provider: amazon-bedrock, region us-east-2
  • Model: global.anthropic.claude-opus-5 (adaptive thinking is always on)
  • Also reproduced by others on Fable 5 (#31687) and Claude with extended thinking (#36517)

Evidence

61 distinct log lines carrying this error in my local logs, spanning
2026-06-10 → 2026-09-09 — three continuous months, across multiple agents
(primary and subagents), and still occurring on the latest release.

The offending wire shape, reduced to the relevant structure:

{ "role": "user",      "content": [ { "...": "..." }, { "cachePoint": { "type": "default" } } ] },
{ "role": "assistant", "content": [ { "text": "..." },
                                    { "reasoningContent": { "reasoningText": { "text": "..." } } },
                                    { "cachePoint": { "type": "default" } } ] }

The trailing cachePoint after reasoningContent is what Bedrock rejects.

The fix already exists

PR #36532 by @giggling-ginger. The branch is still live at
giggling-ginger/opencode@bedrock-cache-reasoning (d7ec996), and the diff still serves
from https://github.com/anomalyco/opencode/pull/36532.diff.

It is ~25 lines of logic across three source files plus three test files:

  • packages/llm/src/cache-policy.ts — mark at
    content.findLastIndex(p => p.type !== "reasoning") instead of content.length - 1,
    and bail when no safe index exists
  • packages/opencode/src/provider/transform.ts — new applyBedrockCacheOptions(): when an
    assistant message ends in reasoning, attach providerOptions to the last non-reasoning
    part instead of at message level; skip entirely for reasoning-only messages
  • packages/llm/src/protocols/bedrock-converse.ts — comment

Before / after wire layout:

before:  text → reasoning → cachePoint   ❌ ValidationException
after:   text → cachePoint → reasoning   ✅

I have read this diff and it addresses the root cause at the correct layer. It needs a
maintainer to look at it, not to be rewritten.

There is no user-side workaround

Worth stating explicitly, because it affects priority: this cannot be worked around with
a plugin.
I verified against the published @opencode-ai/plugin@1.18.31 types:

  • The only message-level hook, experimental.chat.messages.transform, receives opencode's
    own { info: Message, parts: Part[] } domain objects. It runs before conversion to AI
    SDK ModelMessages and before applyCaching, so no cachePoint exists yet to strip
    or relocate.
  • aisdk.language and aisdk.sdk are not part of the public Hooks interface — they are
    available only to opencode's internal provider plugins — so a language-model wrapper that
    sanitises the outgoing prompt is not possible either.
  • chat.params exposes temperature/topP/topK/maxOutputTokens/options, none of which
    influence cache-point placement.

There is also no configuration lever: the published config schema
(https://opencode.ai/config.json) contains no cache-related key anywhere. PR #5422, which
would add provider.*.cache.enabled, has been open since 2025-12-12.

So affected users are left with either manual /undo on every occurrence, or maintaining a
patched build of a repo that pushes multiple commits a day.

Requested action

Review and merge PR #36532, or reopen it so the author can rebase. If the approach needs
changing, a review comment saying so would at least let someone act on it — the current
state is that a correct, tested fix was thrown away by automation without being read.

Suggestion, separately: excluding PRs that close an open bug from automated-pr-cleanup
would prevent this specific failure mode from recurring.

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.

Research direction

Start by reading the referenced PR #36532 diff and the three named files: packages/llm/src/cache-policy.ts, packages/opencode/src/provider/transform.ts, and packages/llm/src/protocols/bedrock-converse.ts. Run its six regression tests and typecheck, then verify that Bedrock requests place cache points before trailing reasoning blocks and avoid them for reasoning-only messages.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
backend, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.