[BUG] OTel: api_request event missing for most requests whose response contains text (only assistant_response is logged); side queries log neither

Status Open
Reported on v2.1.284
Maintainer reply None cached
Activity 0 comments · opened Sep 29, 2026

What's wrong

The monitoring docs say the claude_code.api_request event "is logged for each API request to Claude", and that claude_code.assistant_response is logged after each API request that returns text content. In practice, when a response contains text, Claude Code usually logs only assistant_response and no api_request for that request. Side queries such as auto_mode and agent_classifier log neither event.

assistant_response carries no cost_usd and no token counts, so any consumer that reads per-request cost from api_request misses these requests. In our data that is about a third of all LLM requests.

What should happen

One api_request event, with cost_usd and token counts, for every API request, including requests whose response contains text and side queries. If some requests are excluded on purpose, the docs should say which.

Steps to reproduce

Telemetry on (CLAUDE_CODE_ENABLE_TELEMETRY=1, OTLP logs, traces and metrics, CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1), Claude Code 2.1.284:

  1. claude -p "Reply with the single word: done"
  2. Exported: one claude_code.llm_request span (stop_reason=end_turn, success=true, tokens present) and one assistant_response log event with the same request_id.
  3. Not exported: any api_request log event for that request_id.
  4. The claude_code.cost.usage metric for the session is non-zero, and the claude_code.token.usage totals equal the span's tokens.

Variant: ask it to run one Bash command and then reply. The tool-call request gets api_request. The final text reply gets assistant_response only.

Impact

Across about 29k llm_request spans over 7 days, from several developers on versions 2.1.251 through 2.1.284, joined to log events by request_id:

| Log events for the request | Share of requests |
|---|---|
| api_request only (tool-use response, no text) | 64% |
| api_request + assistant_response (the documented behavior) | 3% |
| assistant_response only | 27% |
| neither (side queries: auto_mode, agent_classifier, agent_summary, …) | 6% |

  • Only about 11% of text-bearing responses get an api_request. Per version it ranges from 6% to 17%, so it isn't a recent regression.
  • Every end_turn response contains text, so 84–91% of end_turn requests have no api_request.
  • It isn't exporter loss. For each affected request, the assistant_response event with the same request_id arrives through the same exporter.
  • The claude_code.cost.usage metric does count these requests. Over the same week its total was 1.64× the sum of cost_usd on api_request events. Cost is tracked internally but not emitted per request.

Also observed (possibly related)

  • #64436 and #89406 describe OTel logs lost on shutdown or stopping mid-session. This looks different: the sibling assistant_response event for the same request is exported, and the gap reproduces on a single short -p call.

Environment

  • Claude Code 2.1.284 (probe); 2.1.251–2.1.284 (aggregate data)
  • macOS (Darwin 25.6.0)
  • OTLP http/protobuf exporter for logs, traces and metrics

View original on GitHub ↗