[BUG] Built-in OTEL does not emit `claude_code.user_prompt` events when running in VS Code (terminal.type=non-interactive)
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?
Description
The built-in OpenTelemetry instrumentation in Claude Code does not emit claude_code.user_prompt
log events when running inside the VS Code extension (terminal.type=non-interactive). All other built-in events (api_request, tool_decision, tool_result) are emitted normally from both CLI and VS Code.
Expected Behavior
Both CLI and VS Code sessions should emit claude_code.user_prompt events to the OTEL collector.
Actual Behavior
- CLI (terminal.type: ghostty): emits user_prompt ✅
- VS Code (terminal.type: non-interactive): does NOT emit user_prompt ❌
All other events work from both:
┌───────────────────────────┬─────┬─────────┐
│ Event │ CLI │ VS Code │
├───────────────────────────┼─────┼─────────┤
│ claude_code.user_prompt │ ✅ │ ❌ │
├───────────────────────────┼─────┼─────────┤
│ claude_code.api_request │ ✅ │ ✅ │
├───────────────────────────┼─────┼─────────┤
│ claude_code.tool_decision │ ✅ │ ✅ │
├───────────────────────────┼─────┼─────────┤
│ claude_code.tool_result │ ✅ │ ✅ │
└───────────────────────────┴─────┴─────────┘
Diagnostic Steps Performed
- Verified env vars in VS Code process: All 11 OTEL env vars present, including
OTEL_LOG_USER_PROMPTS=1 and CLAUDE_CODE_ENABLE_TELEMETRY=1. CLAUDE_CODE_ENTRYPOINT=claude-vscode
is set.
- Verified collector accepts user_prompt: Sent synthetic user_prompt event via gRPC — accepted
(HTTP 200, gRPC status 0).
- Verified transcript structure: VS Code transcript contains user messages with identical
structure to CLI (standard {type: "text", text: "..."} blocks, not per-character).
- Local collector intercept: Redirected OTEL_EXPORTER_OTLP_ENDPOINT to localhost:4317 running
otel/opentelemetry-collector-contrib:latest (v0.143.1) with debug exporter. Confirmed CLI emits
user_prompt, VS Code does not.
Environment
- CLI version: 2.1.72 (emits user_prompt correctly)
- VS Code extension version: 2.1.72 (does not emit user_prompt)
- OS: macOS Darwin 25.2.0, arm64
- VS Code terminal.type: non-interactive
- CLI terminal.type: ghostty
What Should Happen?
When a user sends a message through the VS Code extension, the Claude Code binary should emit a claude_code.user_prompt OTEL log event with the same attributes as the CLI version (prompt_length, prompt when OTEL_LOG_USER_PROMPTS=1, session.id, prompt.id, etc.). The user_prompt event is critical for observability because it's the only event that captures the user's input, and without it there's no way to correlate a user's question with the resulting api_request/tool_decision/tool_result chain via prompt.id.
Error Messages/Logs
No errors are produced — the event is silently not emitted. The collector logs show the gap clearly:
CLI session — user_prompt present:
2026-03-11T18:04:45.517Z info ResourceLog #0
Resource attributes:
-> host.arch: Str(arm64)
-> os.type: Str(darwin)
-> os.version: Str(25.2.0)
-> service.name: Str(claude-code)
-> service.version: Str(2.1.72)
ScopeLogs #0
InstrumentationScope com.anthropic.claude_code.events 2.1.72
LogRecord #0
ObservedTimestamp: 2026-03-11 18:04:32.774 +0000 UTC
Timestamp: 2026-03-11 18:04:32.774 +0000 UTC
Body: Str(claude_code.user_prompt)
Attributes:
-> user.id:
Str(1234512345123451234512345)
-> session.id: Str(12345-12345-12345-12345-12345)
-> organization.id: Str(12345-12345-12345-12345-12345)
-> user.email: Str(daniel@example.com)
-> terminal.type: Str(ghostty)
-> event.name: Str(user_prompt)
-> event.timestamp: Str(2026-03-11T18:04:32.774Z)
-> event.sequence: Int(0)
-> prompt.id: Str(12345-12345-12345-12345-12345)
-> prompt_length: Str(7)
-> prompt: Str(ahora ?)
VS Code session — only api_request, tool_decision, tool_result received, zero
user_prompt:
Body: Str(claude_code.api_request) -> session.id: Str(a241d322-...) ->
terminal.type: Str(non-interactive)
Body: Str(claude_code.api_request) -> session.id: Str(a241d322-...) ->
terminal.type: Str(non-interactive)
Body: Str(claude_code.tool_decision) -> session.id: Str(a241d322-...) ->
terminal.type: Str(non-interactive)
Body: Str(claude_code.tool_result) -> session.id: Str(a241d322-...) ->
terminal.type: Str(non-interactive)
Body: Str(claude_code.api_request) -> session.id: Str(a241d322-...) ->
terminal.type: Str(non-interactive)
No claude_code.user_prompt log record appears for any VS Code session. The collector debug exporter (verbosity: detailed) captures every incoming record — the event is simply never sent by the binary.
Steps to Reproduce
- Configure OTEL telemetry in ~/.claude/remote-settings.json (or settings.json):
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_LOG_USER_PROMPTS": "1",
"OTEL_LOG_TOOL_DETAILS": "1"
}
}
- Run a local OTEL collector with debug exporter (e.g., otel/opentelemetry-collector-contrib with
verbosity: detailed)
- Open Claude Code in CLI → send a message → observe collector logs
- Open Claude Code in VS Code → send a message → observe collector logs
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.72
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
The binary appears to have separate code paths for receiving user input in CLI (stdin) vs VS Code (IPC/webview). The user_prompt OTEL event seems to only be instrumented on the CLI/stdin path. Events emitted during processing (api_request, tool_decision, tool_result) share the same pipeline and work from both entrypoints
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗