Feature Request: Propagate TRACEPARENT to subprocess environments for trace hierarchy

Resolved 💬 3 comments Opened Jan 8, 2026 by sunholo-voight-kampff Closed Feb 22, 2026

Summary

When Claude Code executes tools (especially Bash), the child process does not receive the OpenTelemetry trace context (TRACEPARENT environment variable). This breaks distributed tracing for applications that spawn subprocesses from Claude Code tool execution.

Problem

When building observability around Claude Code, we want to see the full trace hierarchy:

claude.execute
  └── exec.turn
        └── exec.tool_use (Bash: ailang check ...)
              └── ailang.check (child process)  ← NOT LINKED
                    └── compile.parse
                    └── compile.typecheck

Currently, child spans created by subprocesses end up in completely different traces because TRACEPARENT is not propagated:

Trace 1: claude.execute → exec.turn → exec.tool_use
Trace 2: ailang.check → compile.parse (orphaned, different trace_id!)

Proposed Solution

When Claude Code spawns a subprocess for tool execution (especially Bash), propagate the current trace context via environment variables:

# Standard W3C Trace Context format
TRACEPARENT=00-{trace_id}-{span_id}-01

This is the standard approach used by:

  • OpenTelemetry auto-instrumentation
  • Jaeger, Zipkin, and other tracing systems
  • Most CI/CD systems (GitHub Actions, GitLab, etc.)

Use Case

We're building AILANG, a language for AI code synthesis. Our observability system (Observatory) tracks:

  • Coordinator tasks that delegate to Claude Code
  • Claude Code execution (turns, tool uses)
  • Child processes spawned by Claude (ailang check, ailang run, etc.)

Without TRACEPARENT propagation, we have to use timestamp-based correlation as a workaround, which is fragile and only works when all spans are in the same trace.

Workaround (Current)

We currently work around this by:

  1. Using task_id attributes instead of trace_id for linking
  2. Timestamp-based correlation for spans within the same trace
  3. Script-based agents that explicitly set TRACEPARENT before calling ailang exec

These workarounds add complexity and don't provide true distributed tracing.

Implementation Notes

The fix would be minimal - when spawning a subprocess, include the current span's trace context in the environment:

// Pseudocode
env := os.Environ()
if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
    traceparent := fmt.Sprintf("00-%s-%s-01", 
        span.SpanContext().TraceID().String(),
        span.SpanContext().SpanID().String())
    env = append(env, "TRACEPARENT="+traceparent)
}
cmd.Env = env

Environment

  • Claude Code version: Latest
  • OS: macOS, Linux
  • Using OTEL exporter to local collector

Related

This would enable proper integration with any OTEL-compatible tracing system and improve the developer experience for anyone building observability around Claude Code.

---

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗