Repository navigation
Description
What happened?
When Claude Code talks to a GPT model through an Anthropic-compatible gateway, the transcript's message.id is the upstream OpenAI Responses id (resp_…), and the line has no requestId key. Claude Code still writes one line per content block, each with its own timestamp and the full usage of the response. This is the same shape as #1837, only with a resp_ id.
In 20.0.36, usage_dedupe_hash (rust/adapters/claude/src/lib.rs) scopes requestless entries by session and timestamp (#1799). #1838 dropped the timestamp for msg_ ids through is_anthropic_message_id, which daily.rs also uses. A resp_ id keeps the timestamp in its key, so every content-block line is counted. On one machine's real logs, the daily total for GPT-model traffic roughly doubled between 20.0.19 and 20.0.36.
The doc comment on is_anthropic_message_id calls the prefix a heuristic because a gateway can reuse one placeholder id for every response. resp_ ids are not gateway placeholders. OpenAI's Responses API mints one per response and the gateway passes it through, so they are unique per response the same way msg_ ids are. A gateway that minted a constant resp_ placeholder would collapse to one entry per session, the same risk the comment already accepts for msg_.
A gateway could also return a request-id header so that Claude Code records a requestId on new turns (not tested). Transcripts already on disk would still have none.
Steps to reproduce
d=$(mktemp -d)
mkdir -p "$d/projects/repro"
u='{"input_tokens":1000,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":100}'
for ts in 2025-01-05T12:00:00.573Z 2025-01-05T12:00:00.575Z; do
printf '{"type":"assistant","sessionId":"s1","timestamp":"%s","message":{"id":"resp_0123456789abcdef","type":"message","role":"assistant","model":"gpt-5.5","usage":%s}}\n' "$ts" "$u"
done > "$d/projects/repro/s1.jsonl"
CLAUDE_CONFIG_DIR="$d" npx [email protected] daily --json --offline --since 20250105 --until 20250105 | jq .totals.totalTokens20.0.36 prints 2200. [email protected] prints 1100. With the id changed to msg_0123456789abcdef, both versions print 1100.
Expected behavior
The two lines share one message.id, so they count once (1100), as the msg_ case does in requestless_anthropic_message_id_content_blocks_are_counted_once_in_every_report. Treating resp_ like msg_ in is_anthropic_message_id (perhaps under a broader name), with that test mirrored for resp_, would cover it.
Version
20.0.36
About how this report was produced
Claude Code (an AI coding agent) drafted this report on the account owner's machine. It found the doubling while reconciling token totals across usage tools, built the repro above, and ran it against 20.0.19 and 20.0.36.
Activity
pullfrog commentedon Oct 19, 2026
github-actions commentedon Oct 19, 2026
Pullfrog triage: priority:high
Kind: bug
Maintenance fit: maintainable
Confidence: high
Requestless content-block lines with resp_ ids are counted once per block instead of once per response. Repro shows 2200 versus expected 1100 and doubling since 20.0.19, continuing accepted bug 1837 fixed for msg_ ids only. Material usage overcount with clear evidence and bounded dedupe fix.
Decision: kept open; Pullfrog will attempt a focused implementation PR.
fix(claude): count requestless resp_ content blocks once (ccusage#1935)