[BUG] Fork subagent transcript duplicates the parent's last response (same requestId and usage), so per-file usage counts it twice
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
A fork subagent's transcript (subagents/agent-*.jsonl, isFork: true in agent-*.meta.json) starts with a copy of the parent's last assistant response: the one whose Agent tool call launched the fork. The copy has the same message.id, the same requestId and the same usage as the record in the parent transcript, and nothing marks it as a copy. The API request happened once, but its usage is now on disk twice.
Record order in the fork transcript:
{"type":"fork-context-ref", ...}assistant: the copy (parentUuid: null,isSidechain: true, content ends withtool_useAgent)user: the fork's promptassistant: the fork's own first response
Only parentUuid: null and the position (after fork-context-ref, before the first user record) tell the copy apart. isSidechain: true is on every record of every subagent transcript, so it doesn't help.
Example from a fork I launched on 2.1.284 just to check this (usage shown as input / cache read / cache write / output):
| | Parent transcript | Fork transcript, record 2 |
|---|---|---|
| message.id | msg_011CfWTRNj8vvFCKLx9ERTMD | same |
| requestId | req_011CfWTRMDMXXa6WydCMwamm | same |
| usage | 2 / 291,524 / 1,769 / 460 | same |
| records | 3 (thinking, thinking, tool_use Agent) | 1, a copy of the parent's last record (tool_use Agent) |
Any tool that computes usage or cost per transcript file, which is the natural way to get per-subagent numbers, counts that response twice: once for the parent, once for the fork. Priced at claude-opus-5-5 rates, this one copy is $0.082, mostly the parent's full-context cache read. Each fork adds one such copy.
Tools that deduplicate by requestId across all files of a session avoid it. Tools that deduplicate within a file don't.
What Should Happen?
The copied context record should not look like a response the fork made. Either of these would do:
- mark it, e.g.
"isForkContext": true, so readers can skip it, or - omit
usagefrom the copy, since the request is billed to, and already recorded in, the parent transcript.
Error Messages/Logs
No error output. Counts over all subagent transcripts on this machine:
kind version files fork-context-ref copied parent record requestId also in parent transcript
fork 2.1.268 4 4 4 4
fork 2.1.270 3 3 3 3
fork 2.1.280 15 15 15 15
fork 2.1.284 1 1 1 1
other 2.1.261 to 2.1.283 75 0 0 0
On 2.1.268 and 2.1.270 the copy carried a partial output_tokens (for example 4, against 9,502 in the parent), but its input and cache fields matched the parent. On 2.1.280 and 2.1.284 the whole usage matches.
Steps to Reproduce
- In an interactive session, have Claude launch an agent with
subagent_type: "fork", for example "launch a fork that repliesdonewithout using tools". - Open the newest
agent-*.jsonlin~/.claude/projects/<project>/<session-id>/subagents/(its.meta.jsonhas"isFork": true). - Record 2 is an
assistantrecord withparentUuid: null. Search the parent<session-id>.jsonlfor itsrequestId: the same response is there, with the samemessage.idandusage.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.284 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
Related, not the same bug: #93620 (subagent transcripts end with partial usage). That one makes per-file totals too low; this one makes them too high by one parent response per fork.