Skip to content

fix: register OTel context manager so AI SDK spans thread into Effect traces#22645

Merged
kitlangton merged 1 commit into
devfrom
fix/otel-context-manager
Apr 15, 2026
Merged

fix: register OTel context manager so AI SDK spans thread into Effect traces#22645
kitlangton merged 1 commit into
devfrom
fix/otel-context-manager

Conversation

@kitlangton
Copy link
Copy Markdown
Contributor

Summary

  • Register AsyncLocalStorageContextManager on the global @opentelemetry/api context before the @effect/opentelemetry NodeSdk layer is created
  • Adds @opentelemetry/api and @opentelemetry/context-async-hooks as direct dependencies (both were already transitive)

Problem

Every AI SDK span (ai.streamText, ai.streamText.doStream, ai.toolCall) appeared as a singleton trace — no parent-child threading. Effect spans worked fine (300+ spans in a single trace), but AI SDK spans each started a new trace.

Root Cause

@effect/opentelemetry's NodeSdk creates a NodeTracerProvider but never calls provider.register(). Without that call, no AsyncLocalStorageContextManager is set on the global @opentelemetry/api context. The AI SDK's tracer.startActiveSpan() calls context.active() which returns ROOT_CONTEXT every time → every span starts a new trace.

Evidence (via motel)

Before: ai.streamText on traceId f0fa2077... (spanCount: 1), ai.streamText.doStream on traceId 30ddcf61... (spanCount: 1) — even the AI SDK's own parent/child is broken.

After: SessionPrompt.prompt trace has 400 spans — Effect + AI SDK all threaded together under a single traceId.

… traces

@effect/opentelemetry creates a NodeTracerProvider but never calls
register(), leaving the global @opentelemetry/api context manager as
the no-op default. The AI SDK calls tracer.startActiveSpan() which
relies on context.active() to find parent spans — without a real
context manager every AI SDK span started a new trace.

Registering AsyncLocalStorageContextManager before the NodeSdk layer
fixes this. Verified with motel: traces went from singleton AI SDK
spans to 400+ spans properly threaded under SessionPrompt.prompt.
@kitlangton kitlangton enabled auto-merge (squash) April 15, 2026 16:29
@kitlangton kitlangton merged commit 9640d88 into dev Apr 15, 2026
14 checks passed
@kitlangton kitlangton deleted the fix/otel-context-manager branch April 15, 2026 16:35
xywsxp pushed a commit to xywsxp/opencode that referenced this pull request Apr 24, 2026
dgokeeffe pushed a commit to dgokeeffe/opencode-databricks that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant