fix(core): prefer OTEL trace ID over external span when trace IDs differ#1542
Open
fix(core): prefer OTEL trace ID over external span when trace IDs differ#1542
Conversation
When both an OTEL current span (set by the agent runtime) and an external span (from OpenInference LangChain instrumentor) exist with different trace IDs, get_parent_context() now returns the OTEL span. Previously, the depth-based tiebreaker would pick the external span, causing the agent's trace ID to be lost. Downstream services (ECS) received a different trace ID than the agent trace, making correlation impossible. Validated locally: the x-uipath-traceparent-id header now carries the same trace ID as the agent trace. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iffer Verifies that when the OTEL current span (agent runtime) and the external span (OpenInference) have different trace IDs, the @Traced decorator inherits the OTEL trace ID. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…test Updated test_ctx_parameter_required_when_external_deeper_than_current to assert the new behavior: when OTEL and external spans have different trace IDs, OTEL span is preferred. Removed the duplicate test from test_external_integration.py. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
RunnanJia
approved these changes
Apr 2, 2026
JosephMar
approved these changes
Apr 2, 2026
saksharthakkar
approved these changes
Apr 2, 2026
Contributor
|
@akshaylive I vaguely remember for simulated tools you had a scenario where you needed Openinference trace id and not manual instrumentation Id... please take a look, just wanted to check if your scenario is not affected by this change. |
akshaylive
reviewed
Apr 3, 2026
Collaborator
akshaylive
left a comment
There was a problem hiding this comment.
Could you demonstrate running multiple evals in parallel using simulation in the PR description please?
| span_capture: SpanCapture, | ||
| ): | ||
| """Test that trace.get_current_span(ctx) is required when external span is deeper. | ||
| """Test that OTEL span is preferred when trace IDs differ from external span. |
Collaborator
There was a problem hiding this comment.
This test name is different from the intention. Could you add a test instead of replacing this please?
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.
Summary
When both an OTEL current span (agent runtime) and an external span (OpenInference LangChain instrumentor) exist with different trace IDs,
get_parent_context()now returns the OTEL span.Problem
The agent runtime sets an OTEL span with the agent's trace ID. The OpenInference LangChain instrumentor creates its own spans with a separate trace ID. When the Python SDK makes HTTP calls to downstream services (ECS, LLM Gateway),
_get_bottom_most_span()would pick the OpenInference span because the depth-based tiebreaker defaulted to the external span.Result: the
x-uipath-traceparent-idheader carried a different trace ID than the agent trace, making it impossible to correlate agent traces with CG/ECS logs.Fix
In
_get_bottom_most_span(), when the two spans have different trace IDs, return the OTEL current span immediately (before the depth comparison). The existing depth logic still applies when trace IDs match.Validation
Tested locally: ran an agent with a CG semantic search tool, confirmed the header's trace ID matches the agent's TraceId.
Test plan
x-uipath-traceparent-idheader matches agent TraceId🤖 Generated with Claude Code