Investigate reported zero cache usage with Claude Code via OpenCode Go

Author: YongzhaoooCreated Sep 12, 2026Updated Sep 12, 2026

Update: attribution root-cause hypothesis withdrawn

Further verification does not support the proposed attribution-header fix for the current-version custom-base-URL case. PR #1792 is being withdrawn. The originally reported OpenCode Go cache/usage symptom remains unresolved; this update does not establish a CCR defect or claim that the upstream symptom has been fixed.

The official Claude Code gateway protocol documentation states:

From Claude Code v2.1.181, the block is stable for the lifetime of a conversation when requests route through a custom base URL.

Before v2.1.181 the block contained a per-request token. The environment-variable documentation scopes that workaround to those older versions. This does not justify defaulting CLAUDE_CODE_ATTRIBUTION_HEADER=0 for all CCR-managed Claude Code profiles based on the original report.

Local reproduction

On Windows, the installed Claude Code 2.1.220 CLI sent actual requests to an isolated loopback receiver returning synthetic Anthropic responses. Each of three sessions completed three successive turns using model name deepseek-v4.1-flash, with the attribution variable unset, set to 0, and set to 1 respectively.

Setting Attribution text in JSON system System content across three turns
Unset Present, unchanged Identical
0 Absent Identical
1 Present, unchanged Identical

The captured line was:

x-anthropic-billing-header: cc_version=2.1.220.35b; cc_entrypoint=sdk-cli;

There was no per-turn cch variation. This line was prompt text inside the request body, not an HTTP header. All nine requests included cache_control markers despite the non-Claude model name.

These checks used print/stream-json mode with tools, hooks, and MCP disabled, isolated settings, and no persisted sessions. They did not use --bare, which itself skips attribution. No request was sent to OCG, and no real cache-hit or billing improvement was measured. Other client builds, modes, and production routing paths were not tested.

Public OpenCode code check

At public source revision 95daf90670b7c039c436c85537da5fbfe2205b41, local checks of the exported Anthropic response/chunk converters mapped synthetic prompt_tokens_details.cached_tokens: 800 to cache_read_input_tokens: 800. Thus the original blanket claim that the compatibility code cannot map this field is unsupported.

This does not prove the deployed OCG service uses those converters. The public inference proxy forwards migrated workspaces to a separate inference service. Whether that service uses the attribution text for other purposes remains unknown. Its behavior must not be inferred from the separate x-opencode-session HTTP header.

Remaining reported symptom

Cache usage was reported as zero across successive Claude Code / CCR / OpenCode Go turns. A zero cache_read_input_tokens field alone does not distinguish actual cache misses from missing or differently normalized usage reporting. The initial claims of universal 100% cache misses and verified recovery are withdrawn.

A further investigation needs the exact client/CCR versions, resolved provider/model/protocol, sanitized outgoing prefixes, raw upstream usage, and provider billing/cache evidence from the same requests. Live reproduction is currently unavailable because the account's OCG quota is exhausted. OpenCode Go import and session-header work remain separate in #1785 / #1786.

Source: musistudio/claude-code-router