fix(effect): Honor external parents and isolate root spans - #23900
Open
JPeer264 wants to merge 1 commit into
Open
fix(effect): Honor external parents and isolate root spans#23900JPeer264 wants to merge 1 commit into
JPeer264 wants to merge 1 commit into
Conversation
JPeer264
requested review from
mydea and
nicohrubec
and removed request for
a team
September 2, 2026 07:09
JPeer264
marked this pull request as draft
September 2, 2026 07:09
`@sentry/effect` ignored `Tracer.ExternalSpan` parents and fell back to the active Sentry span. An incoming `traceparent` header on an Effect HTTP server or a persisted trace continued with `Tracer.externalSpan` therefore started a disconnected trace, and a `root: true` span or a span leaked from another fiber through the async context could become the parent of an unrelated span. On the server, every parentless span also shared the process-wide propagation context, so a long-lived process put all of its work into one trace. - An external parent now continues its trace as a new root span with the external span as `parent_span_id`. No dynamic sampling context is frozen, so the SDK builds one from the client. - A parentless span only nests under a foreign active Sentry span (an `http.server` span from the Node SDK, a pageload), never under a span this tracer created. - The server tracer starts a new trace for every parentless span, unless the user set up the current scope (`continueTrace`, `withScope`, an isolation scope). The client tracer keeps parentless spans in the page trace. These fixes apply to both trace lifecycles. One related limitation stays and is specific to `traceLifecycle: 'static'`: a child span that ends after its root span is dropped with the transaction. Long-running Effect fibers, such as a background agent that outlives the request that started it, lose those children unless `traceLifecycle: 'stream'` is used, which sends every span on its own end and is the default since v11. The effect-3-node and effect-4-node e2e apps cover an incoming traceparent header, a `Tracer.externalSpan` parent, and a `root: true` span inside a request. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
JPeer264
force-pushed
the
jp/effect-sdk-trace-structure
branch
from
September 2, 2026 07:30
07eefa2 to
61b80c5
Compare
Contributor
size-limit report 📦
|
JPeer264
marked this pull request as ready for review
September 2, 2026 07:43
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@sentry/effectignoredTracer.ExternalSpanparents and fell back to the active Sentry span. An incomingtraceparentheader on an Effect HTTP server or a persisted trace continued withTracer.externalSpantherefore started a disconnected trace, and aroot: truespan or a span leaked from another fiber through the async context could become the parent of an unrelated span. On the server, every parentless span also shared the process-wide propagation context, so a long-lived process put all of its work into one trace.parent_span_id. No dynamic sampling context is frozen, so the SDK builds one from the client.http.serverspan from the Node SDK, a pageload), never under a span this tracer created.continueTrace,withScope, an isolation scope). The client tracer keeps parentless spans in the page trace.The effect-3-node and effect-4-node e2e apps cover an incoming traceparent header, a
Tracer.externalSpanparent, and aroot: truespan inside a request.