Background sessions (claude agents) drop work-phase OTEL logs (user_prompt/api_request) on shutdown
Summary
Background sessions dispatched via claude agents do not export their work-phase OpenTelemetry logs (user_prompt, api_request, tool_result, tool_decision) to the configured OTLP endpoint. Only the early bootstrap events (plugin_loaded, hook_registered, mcp_server_connection, hook_execution_complete) arrive. Interactive sessions and claude -p runs export everything correctly.
The user-visible effect: a productivity/observability dashboard built on Claude Code telemetry shows no prompts and no API activity for background-agent sessions, even though those sessions run to completion and clearly make API calls.
Environment
- Claude Code: 2.1.159
- OS: macOS (Darwin 25.5.0), Apple Silicon
- Telemetry:
CLAUDE_CODE_ENABLE_TELEMETRY=1, OTLP exporter over gRPC to a self-hosted collector (OpenTelemetry Collector → VictoriaLogs).OTEL_LOGS_EXPORTER=otlp,OTEL_METRICS_EXPORTER=otlp.
Expected behavior
A background session dispatched via claude agents should emit the same log events as an interactive or -p session — in particular claude_code.user_prompt for the dispatched task and claude_code.api_request for each model call.
Actual behavior
The dispatched worker session emits only bootstrap events. The work-phase events never reach the OTLP endpoint.
Reproduction
- Configure OTLP telemetry in
~/.claude/settings.json(CLAUDE_CODE_ENABLE_TELEMETRY=1+ OTLP exporter to a collector you can query). - Run
claude agents, type a trivial task (e.g.Run: echo HELLO-<unique-nonce>, then stop), press Enter to dispatch a background session. - Wait for the session to reach Completed in the agents view (its output is correct — it ran).
- Query the collector/log backend for that session.
Observed in the log backend for the dispatched session:
event.name count
------------------- -----
plugin_loaded 15
hook_registered 3
mcp_server_connection 2
hook_execution_complete 1
user_prompt 0 <-- missing
api_request 0 <-- missing
tool_result 0 <-- missing
tool_decision 0 <-- missing
The unique nonce from the task prompt is nowhere in the backend. A normal claude -p "<same task>" run in the same environment, by contrast, produces user_prompt (with the prompt body when OTEL_LOG_USER_PROMPTS=1), api_request, and tool_result as expected.
The two dispatched worker sessions in our run were created at the dispatch moment and contained only the bootstrap event set above.
Likely root cause (hypothesis)
The bootstrap events are emitted during session init and make it into an early log batch that flushes. The work-phase events (user_prompt, api_request, …) are emitted afterward and appear to be lost when the supervisor terminates the detached worker — i.e., the OTLP log batch processor is not force-flushed on background-session shutdown. Metrics and the initial bootstrap batch survive; the pending work-phase log batch does not.
This is consistent with:
claude -p(graceful foreground exit) exporting everything, includinguser_prompt+ body.- Interactive sessions (long-lived) exporting everything.
- Only
claude agentsdetached/supervised workers (short-lived, terminated by the supervisor) losing the work-phase logs.
It does not appear to be a startup race (the work events are emitted well after the event logger initializes) nor a redaction issue (the events are entirely absent, not <REDACTED>).
Impact
Any observability/cost/productivity tooling built on Claude Code OTLP logs under-reports or entirely misses background-agent activity. Background agents are increasingly used for autonomous/fleet workflows, so their telemetry being invisible is a meaningful gap.
Suggested fix
Force-flush (or graceful-shutdown) the OTLP log provider when a background/claude agents worker session terminates, the same way a -p/interactive session does on clean exit. A SIGTERM handler that calls the logger provider's forceFlush()/shutdown() before exit would likely resolve it.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗