openclaw - 💡(How to fix) Fix [Bug]: ACPX model forwarding to Claude Code triggers prompt cache invalidation on every turn [1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63348Fetched 2026-04-09 07:55:00
View on GitHub
Comments
1
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
commented ×1

When ACPX drives a Claude Code session via ACP, the Anthropic prompt cache is invalidated on the majority of turns, forcing full cache recreation (~90K+ tokens) instead of cache reads. The issue does not occur when using Claude Code CLI directly on the same session.

Root Cause

  • Related: #58488 (ACPX model forwarding uses Claude-specific _meta convention)
  • The root cause may be in ACPX, claude-agent-acp, or Claude Code itself — the logs don't definitively pinpoint which layer is responsible for the model mismatch or the /model command injection
  • Not tested on 2026.4.7 or 2026.4.8 yet; release notes for those versions don't mention a fix for this specific issue

Code Example

Time                   Model   CacheCreate     CacheRead  Notes
    19:04:09  claude-sonnet-4-6        89,771        11,027   CACHE RECREATED
    19:12:06  claude-sonnet-4-6        90,110        11,027   CACHE RECREATED
    19:12:51  claude-sonnet-4-6        90,628        11,027   CACHE RECREATED
    19:13:24  claude-sonnet-4-6        90,891        11,027   CACHE RECREATED
    19:13:52  claude-sonnet-4-6        91,088        11,027   CACHE RECREATED
    19:14:33  claude-sonnet-4-6        91,285        11,027   CACHE RECREATED
    19:15:09  claude-sonnet-4-6        91,543        11,027   CACHE RECREATED
    19:15:48  claude-sonnet-4-6        91,723        11,027   CACHE RECREATED

---

19:28:12  claude-opus-4-6        102,431        11,299   model switch (expected recreation)
    19:28:41  claude-opus-4-6             96       113,730   cache stable
    19:29:45  claude-opus-4-6            129       113,826   cache stable
    19:30:52  claude-opus-4-6            211       113,955   cache stable
    ... (all subsequent turns stable)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug

Beta release blocker

No

Summary

When ACPX drives a Claude Code session via ACP, the Anthropic prompt cache is invalidated on the majority of turns, forcing full cache recreation (~90K+ tokens) instead of cache reads. The issue does not occur when using Claude Code CLI directly on the same session.

Steps to reproduce

  1. Have an ACPX-bound agent configured (e.g. Discord binding with claude-agent-acp)
  2. Send several messages to the agent through the bound channel
  3. Inspect the Claude Code session JSONL at ~/.claude/projects/<project>/<session-id>.jsonl
  4. Compare cache_creation_input_tokens vs cache_read_input_tokens across turns

Expected behavior

After the initial turn creates the cache, subsequent turns should show high cache_read_input_tokens and near-zero cache_creation_input_tokens — same as when using Claude Code CLI directly.

Actual behavior

24 out of 57 turns show full cache recreations (~90K tokens each). The session JSONL shows all ACPX-driven turns hitting the API as claude-sonnet-4-6. When the user switched to direct CLI interaction on the same session (last ~30 turns), the model reported as claude-opus-4-6 and cache stabilized immediately — no more recreations.

Two observations:

  1. ACPX appears to be driving Claude Code with Sonnet rather than the user's intended model (Opus). Whether this is a /model default command being injected or the _meta.claudeCode.options.model forwarding mechanism is unclear from the session logs alone.
  2. Every ACPX-driven turn injects <local-command-stdout>Set model to claude-sonnet-4-6</local-command-stdout> into the conversation, which may be mutating the message prefix and invalidating the cache even when the model doesn't actually change.

OpenClaw version

2026.4.5

Operating system

Ubuntu (Linux 6.8.0-107-generic)

Install method

npm global

Model

anthropic/claude-opus-4-6 (intended); claude-sonnet-4-6 (what ACPX forwarded)

Provider / routing chain

openclaw -> acpx -> @agentclientprotocol/claude-agent-acp@^0.25.0 -> Claude Code CLI -> Anthropic API

Additional provider/model setup details

ACPX session state shows:

  • agentCommand: "npx -y @agentclientprotocol/claude-agent-acp@^0.25.0"
  • protocolVersion: 1
  • Agent capabilities include claudeCode.promptQueueing: true

The agent's model config in OpenClaw is set to use Opus, but the session JSONL shows all ACPX-driven API calls going to claude-sonnet-4-6.

Logs, screenshots, and evidence

See attached cache-invalidation-log.txt for the full per-turn breakdown.

Key pattern — ACPX-driven turns (sonnet, frequent recreations):

    Time                   Model   CacheCreate     CacheRead  Notes
    19:04:09  claude-sonnet-4-6        89,771        11,027   CACHE RECREATED
    19:12:06  claude-sonnet-4-6        90,110        11,027   CACHE RECREATED
    19:12:51  claude-sonnet-4-6        90,628        11,027   CACHE RECREATED
    19:13:24  claude-sonnet-4-6        90,891        11,027   CACHE RECREATED
    19:13:52  claude-sonnet-4-6        91,088        11,027   CACHE RECREATED
    19:14:33  claude-sonnet-4-6        91,285        11,027   CACHE RECREATED
    19:15:09  claude-sonnet-4-6        91,543        11,027   CACHE RECREATED
    19:15:48  claude-sonnet-4-6        91,723        11,027   CACHE RECREATED

Direct CLI turns (opus, cache stable):

    19:28:12  claude-opus-4-6        102,431        11,299   model switch (expected recreation)
    19:28:41  claude-opus-4-6             96       113,730   cache stable
    19:29:45  claude-opus-4-6            129       113,826   cache stable
    19:30:52  claude-opus-4-6            211       113,955   cache stable
    ... (all subsequent turns stable)

The session JSONL also shows <local-command-stdout>Set model to claude-sonnet-4-6</local-command-stdout> injected as user message content on every ACPX-driven turn.

Attached files:

  • cache-invalidation-log.txt — readable per-turn summary
  • claude-session-c3f6ae80.jsonl — full Claude Code session with API usage, model strings, and /model injections
  • acpx-session.json — ACPX-side session state showing agent config and message flow

Impact and severity

  • Affected: Users running agents through ACPX → Claude Code ACP binding
  • Severity: High — silent token/cost multiplier with no user-visible indication
  • Frequency: Observed on every ACPX-driven turn in this session
  • Consequence: Significant unnecessary cache creation costs across the session. In this 57-turn session, 24 turns had full ~90K cache recreations that should have been cache reads.

Additional information

  • Related: #58488 (ACPX model forwarding uses Claude-specific _meta convention)
  • The root cause may be in ACPX, claude-agent-acp, or Claude Code itself — the logs don't definitively pinpoint which layer is responsible for the model mismatch or the /model command injection
  • Not tested on 2026.4.7 or 2026.4.8 yet; release notes for those versions don't mention a fix for this specific issue

extent analysis

TL;DR

The most likely fix for the cache invalidation issue is to ensure that ACPX uses the intended model (Opus) instead of the default model (Sonnet) when driving Claude Code sessions.

Guidance

  1. Verify model configuration: Check the ACPX session state and the agent's model config in OpenClaw to ensure that the intended model (Opus) is correctly set.
  2. Investigate model forwarding: Examine the _meta.claudeCode.options.model forwarding mechanism to determine if it is causing the model mismatch between ACPX and Claude Code.
  3. Check for injected commands: Inspect the session JSONL for any injected commands, such as <local-command-stdout>Set model to claude-sonnet-4-6</local-command-stdout>, that may be mutating the message prefix and invalidating the cache.
  4. Test with direct CLI interaction: Compare the behavior of ACPX-driven turns with direct CLI interaction to identify any differences in model usage and cache stability.
  5. Review related issues: Examine related issues, such as #58488, to determine if they are relevant to the current problem and if any fixes or workarounds have been proposed.

Example

No code snippet is provided as the issue is related to configuration and model usage rather than code implementation.

Notes

The root cause of the issue is unclear and may be related to ACPX, claude-agent-acp, or Claude Code itself. Further investigation is needed to determine the exact cause and to develop a definitive fix.

Recommendation

Apply a workaround to ensure that ACPX uses the intended model (Opus) instead of the default model (Sonnet) when driving Claude Code sessions. This may involve modifying the ACPX session state or the agent's model config in OpenClaw.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

After the initial turn creates the cache, subsequent turns should show high cache_read_input_tokens and near-zero cache_creation_input_tokens — same as when using Claude Code CLI directly.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING