Summary
When OTel telemetry is enabled on the SDK subprocess (CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_LOGS_EXPORTER=otlp), the bundled CLI emits claude_code.* log events (user_prompt, api_request_body, tool_decision, hook_execution_complete) with empty trace_id/span_id, while sibling spans (claude_code.interaction, claude_code.tool, claude_code.llm_request) correlate correctly with the parent span via auto-injected TRACEPARENT.
This breaks log↔trace correlation for any SDK app that opens a parent OTel span around query() — the documented integration pattern. The only usable label on the events is the SDK's auto-generated session.id, forcing DB-side joins instead of backend-side trace filtering.
Root cause (upstream)
Tracked in the CLI repo: anthropics/claude-code#63074. The CLI's OTel logger emits from callbacks that have lost AsyncLocalStorage context, so LogRecords ship with an empty spanContext. Spans are unaffected.
Why file here too
The fix lands in the CLI, but SDK users only receive it through the bundled CLI (claude_agent_sdk/_cli_version.py — 0.2.87 bundles 2.1.150). Filing so that:
- SDK users hitting broken log↔trace correlation can find this from the SDK repo.
- Once the CLI fix ships, the bundled CLI bump can be tracked here.
Environment
claude-agent-sdk 0.2.87 (bundled CLI 2.1.150); also reproduced on CLI 2.1.153
- Python 3.14, parent process with active OTel span around
query()
- Subprocess env:
CLAUDE_CODE_ENABLE_TELEMETRY=1, OTEL_LOGS_EXPORTER=otlp, OTEL_LOG_USER_PROMPTS=1, OTEL_LOG_TOOL_DETAILS=1
Summary
When OTel telemetry is enabled on the SDK subprocess (
CLAUDE_CODE_ENABLE_TELEMETRY=1,OTEL_LOGS_EXPORTER=otlp), the bundled CLI emitsclaude_code.*log events (user_prompt,api_request_body,tool_decision,hook_execution_complete) with emptytrace_id/span_id, while sibling spans (claude_code.interaction,claude_code.tool,claude_code.llm_request) correlate correctly with the parent span via auto-injectedTRACEPARENT.This breaks log↔trace correlation for any SDK app that opens a parent OTel span around
query()— the documented integration pattern. The only usable label on the events is the SDK's auto-generatedsession.id, forcing DB-side joins instead of backend-side trace filtering.Root cause (upstream)
Tracked in the CLI repo: anthropics/claude-code#63074. The CLI's OTel logger emits from callbacks that have lost AsyncLocalStorage context, so LogRecords ship with an empty
spanContext. Spans are unaffected.Why file here too
The fix lands in the CLI, but SDK users only receive it through the bundled CLI (
claude_agent_sdk/_cli_version.py— 0.2.87 bundles 2.1.150). Filing so that:Environment
claude-agent-sdk0.2.87 (bundled CLI 2.1.150); also reproduced on CLI 2.1.153query()CLAUDE_CODE_ENABLE_TELEMETRY=1,OTEL_LOGS_EXPORTER=otlp,OTEL_LOG_USER_PROMPTS=1,OTEL_LOG_TOOL_DETAILS=1