Skip to content

Feature request: propagate W3C TRACEPARENT/TRACESTATE into the agent engine (Claude Code) so engine spans join the workflow trace #38905

Description

@yskopets

🤖 This issue has been generated by Claude Code.

Feature request

Propagate the active W3C trace context (TRACEPARENT, and optionally TRACESTATE) into the agent engine process (Claude Code) so the engine's spans nest under the workflow's gh-aw.agent.* span and form a single end-to-end distributed trace.

Background — Claude Code already supports inbound trace context

Per the Claude Code docs (Monitoring → Traces (beta)):

In Agent SDK and non-interactive sessions started with -p, Claude Code also reads TRACEPARENT and TRACESTATE from its own environment when starting each interaction span. This lets an embedding process pass its active W3C trace context into the subprocess so Claude Code's spans appear as children of the caller's distributed trace.

gh-aw runs the engine non-interactively (headless / -p), so the engine is exactly the kind of embedded process that will honor an inbound TRACEPARENT if the embedding process sets one.

Current behavior

gh-aw already computes the active span context and exposes it as its own environment variables — for example, in the agent job the runtime carries:

GITHUB_AW_OTEL_TRACE_ID:       <trace-id>            # the run's traceId
GITHUB_AW_OTEL_PARENT_SPAN_ID: <span-id>             # the gh-aw.agent.setup span

However, that context is injected only into the MCP gateway container (gh-aw-mcpg), via -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID and the gateway's opentelemetry.traceId/spanId config — which is why gateway spans correctly nest under agent.setup. The engine process never receives this context, and no TRACEPARENT/TRACESTATE variable is set anywhere in the compiled workflow or the runtime environment.

As a result, the engine's internal spans cannot join the workflow trace: under gh-aw.agent.setup you see agent.conclusion and the MCP gateway's spans, but never the engine's own claude_code.interaction / claude_code.llm_request / claude_code.tool spans. The agent's prompt → API → tool causality is invisible in the distributed trace.

Requested behavior

For the agent step, set the W3C trace-context variable(s) in the engine process environment, derived from the values gh-aw already has:

TRACEPARENT=00-${GITHUB_AW_OTEL_TRACE_ID}-${GITHUB_AW_OTEL_PARENT_SPAN_ID}-01
# optionally:
TRACESTATE=<propagated tracestate, if any>

gh-aw already holds every byte required (it formats the same context for the gateway today) — this is just emitting it in W3C traceparent form into the engine's environment instead of (only) the gateway-specific variables.

Why it's valuable

  • Complete agent-job traces: the engine's interaction/LLM-request/tool spans nest under gh-aw.agent.setup, closing the current black box between agent.setup and agent.conclusion.
  • Unified causality: engine LLM/tool spans line up with the MCP gateway's gateway.request/mcp.tool_call spans (which already nest under agent.setup) in one trace, so a tool call can be followed from the engine through the gateway to the backend.
  • Standards-based: TRACEPARENT/TRACESTATE are the W3C Trace Context standard; propagating them is engine-agnostic and benefits any engine that reads inbound W3C context, not just Claude Code.

Notes

  • Enabling the engine's own trace exporter (so it actually emits spans) is a separate consumer-side concern; this request is specifically about gh-aw propagating the trace context so that whenever an engine's tracing is active, its spans attach to the correct parent.
  • The natural parent is the per-job span gh-aw already uses for the gateway context (gh-aw.agent.setup), keeping the engine spans and gateway spans siblings under the same parent.

Note: observed in a private repository. Repo/workflow names, run IDs, endpoint URLs, and concrete trace/span IDs are redacted or shown as placeholders; the Claude Code documentation excerpt is quoted verbatim.

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions