[BUG] Built-in OTEL does not emit `claude_code.user_prompt` events when running in VS Code (terminal.type=non-interactive)

Resolved 💬 1 comment Opened Mar 11, 2026 by daniel-hedgineer Closed Mar 13, 2026

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

  1. 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.

  1. Verified collector accepts user_prompt: Sent synthetic user_prompt event via gRPC — accepted

(HTTP 200, gRPC status 0).

  1. Verified transcript structure: VS Code transcript contains user messages with identical

structure to CLI (standard {type: "text", text: "..."} blocks, not per-character).

  1. 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

  1. 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"
}
}

  1. Run a local OTEL collector with debug exporter (e.g., otel/opentelemetry-collector-contrib with

verbosity: detailed)

  1. Open Claude Code in CLI → send a message → observe collector logs
  2. 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

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗