Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneesstack72

#317 Trace context is lost: CLI ignores inbound TRACEPARENT and raw driver doesn't propagate active context into in-process methods

Opened by bixu · 5/11/2026· Shipped 5/11/2026

What's affected

OTel trace propagation across two boundaries inside the swamp CLI:

  1. CLI startup (src/infrastructure/tracing/otel_init.ts) — when OTEL_EXPORTER_OTLP_ENDPOINT is set, swamp initializes a tracer provider with an AsyncLocalStorageContextManager, but never registers a W3C propagator and never extracts an inbound TRACEPARENT env var. The helper extractTraceContext already exists in src/infrastructure/tracing/propagation.ts and is exported from mod.ts, but nothing in src/ calls it — only its own unit test does. Every swamp invocation therefore starts a fresh trace, even when the parent process exported a TRACEPARENT.

  2. Raw execution driver (src/domain/drivers/raw_execution_driver.ts) — MethodExecutionService already calls injectTraceContext() and puts the result on ExecutionRequest.traceHeaders (method_execution_service.ts:655). The docker driver propagates those as env vars to the child container (docker_execution_driver.ts:535-538), but the raw driver ignores request.traceHeaders and runs the method in-process via this.executor.execute(...). An in-process extension method that reads Deno.env.get(\"TRACEPARENT\") sees only whatever the OS-level env had at swamp launch — never the active span swamp just opened for this method.

Observable impact

Concrete repro from @hivemq/mudroom: the wrapper script (bin/mudroom) mints one TRACEPARENT per invocation and exports it before every swamp model method run. The extension's tracer reads Deno.env.TRACEPARENT and parents all its spans under that root. Result, per single mudroom up:

  • One trace in the extension's dataset = the wrapper-synthesized root + every method's spans, all correctly linked.
  • N independent traces in the swamp dataset = one fresh root per swamp model method run subprocess, none linked to the wrapper and none linked to each other.

So extension authors who do the "right thing" (read inbound TRACEPARENT, emit children) still cannot get a unified trace across the wrapper → swamp → method call chain, because the middle hop drops the context twice.

Suggested fix shape

Two changes, both small, both in swamp:

  1. In initTracing(), read Deno.env.get(\"TRACEPARENT\") (and optionally TRACESTATE) and call the existing extractTraceContext helper, then make that context the active root for the CLI invocation. This is the gap extractTraceContext was clearly written to fill.

  2. In RawExecutionDriver.execute, mirror what DockerExecutionDriver already does for request.traceHeaders: surface them to the in-process method. Since the raw driver runs in the same Deno process, either temporarily setting Deno.env[\"TRACEPARENT\"] around the executor call, or running the executor inside an OTel context.with(extractTraceContext(request.traceHeaders), ...), would do it. The env-var route covers extensions whose tracer doesn't pull from the @opentelemetry/api SDK (some extensions hand-roll OTLP to keep their bundle small), so it's the more universally useful of the two.

With #1, swamp's own spans and the wrapper's root share a trace ID, and any extension that already reads TRACEPARENT from env lands on the same trace. #2 additionally nests the extension's spans under the swamp method-execution span instead of leaving them as peers of the wrapper root.

Environment

  • swamp 20260509.235714.0-sha.7ace6b02
  • macOS 26 (Tahoe), arm64
  • OTLP endpoint: Honeycomb EU (https://api.eu1.honeycomb.io)
  • Reproduced via @hivemq/mudroom (2026.05.10.1); same break would occur for any in-process extension with hand-rolled or env-driven trace propagation.
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 3 MOREFINDINGS+ 3 MOREPR_MERGEDSHIPPED

Shipped

5/11/2026, 1:31:06 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack725/11/2026, 1:04:09 PM

Sign in to post a ripple.