Preflight Checklist
What's Wrong?
Session JSONL files (~/.claude/projects/<project>/<session-id>.jsonl) log every content block during streaming but never log
the final message_stop event.
output_tokens in the usage field is a mid-stream snapshot, not the final count
stop_reason is always null, no line ever records "end_turn"
- Output tokens are undercounted by ~2x compared to actual content
- Input/cache token counts are accurate (set at request start)
Evidence
Single API call producing thinking + text + 3 tool_use blocks:
Line 41: thinking output_tokens=8 stop_reason=null
Line 42: text output_tokens=8 stop_reason=null
Line 43: tool_use output_tokens=8 stop_reason=null
Line 45: tool_use output_tokens=8 stop_reason=null
Line 46: tool_use output_tokens=310 stop_reason=null ← partial update, still not final
Full session comparison (128 API calls, Opus 4.6, 49 min):
┌───────────────────────────────────────────┬───────────────┐
│ Method │ Output Tokens │
├───────────────────────────────────────────┼───────────────┤
│ JSONL output_tokens summed │ 23,725 │
├───────────────────────────────────────────┼───────────────┤
│ tiktoken cl100k_base on extracted content │ 45,050 │
├───────────────────────────────────────────┼───────────────┤
│ Undercount │ ~1.9x │
└───────────────────────────────────────────┴───────────────┘
Impact
- Cost tracking tools (ccusage, cccost, custom scripts) that parse JSONL get wrong output counts
- No way to reconcile per-session cost against Anthropic billing dashboard
- Users building usage reports or budgeting around JSONL data are underestimating spend
### What Should Happen?
Each API call should have a final JSONL line with:
- `stop_reason: "end_turn"` (or `"tool_use"`)
- Accurate final `output_tokens` count matching what Anthropic actually bills
This is one additional JSONL line per API call , the final streaming event that currently gets discarded.
### Error Messages/Logs
```shell
{
"type": "assistant",
"requestId": "req_011CYLnnca3yt6Axy4nsUrRM",
"message": {
"role": "assistant",
"stop_reason": null,
"usage": {
"input_tokens": 1,
"cache_creation_input_tokens": 510,
"cache_read_input_tokens": 40716,
"output_tokens": 310
}
}
}
No line in the entire 1043-line JSONL transcript has stop_reason set to anything other than null.
Steps to Reproduce
- Run any Claude Code session with multiple tool calls
- After session ends, open the JSONL transcript at
~/.claude/projects/<project>/<session-id>.jsonl
- Search for
stop_reason , every line shows null
- Sum
output_tokens from the last JSONL line per unique requestId
- Compare against actual output content (extract all thinking/text/tool_use blocks, tokenize with tiktoken)
- Observe ~2x undercount
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
2.1.50
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Session analyzed: 128 API calls, 49 minutes, ~11.3M total input tokens (mostly cached), heavy MCP tool usage. The undercount is consistent across the entire session, not isolated to specific request types.
Preflight Checklist
What's Wrong?
Session JSONL files (
~/.claude/projects/<project>/<session-id>.jsonl) log every content block during streaming but never logthe final
message_stopevent.output_tokensin theusagefield is a mid-stream snapshot, not the final countstop_reasonis alwaysnull, no line ever records"end_turn"Evidence
Single API call producing thinking + text + 3 tool_use blocks:
Steps to Reproduce
~/.claude/projects/<project>/<session-id>.jsonlstop_reason, every line showsnulloutput_tokensfrom the last JSONL line per uniquerequestIdClaude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
2.1.50
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Session analyzed: 128 API calls, 49 minutes, ~11.3M total input tokens (mostly cached), heavy MCP tool usage. The undercount is consistent across the entire session, not isolated to specific request types.