fix(otel): span id collision execution arn scoping#669
Merged
Conversation
Derive the otelTraceSampled boolean from SpanContext.traceFlags (bit 0x01 = W3C sampled flag) and include it in the structured log context alongside traceId and spanId.
Verify the new otelTraceSampled field appears in structured log output in both the OTel plugin unit test and the log-enrichment integration test.
Add a typed PluginOperationStatus const enum to replace the untyped string status field in OperationInfo. The enum contains all operation lifecycle states from the AWS SDK (STARTED, READY, PENDING, SUCCEEDED, FAILED, TIMED_OUT, STOPPED, CANCELLED). Also convert PluginInvocationStatus and AttemptEndInfoOutcome to const enums for consistency.
…sion When parent and child workflows share the same trace context and have operations at the same position (e.g., both at step 1), the deriveSpanIdFromOperationId function previously produced identical span IDs for both. This caused incorrect span parenting where the parent workflow's step span would be nested under the child workflow's step span instead of its own invocation span. The fix adds executionArn as a required parameter to deriveSpanIdFromOperationId and hashes both executionArn and operationId together, ensuring unique span IDs per execution even within the same trace.
SilanHe
marked this pull request as ready for review
June 30, 2026 20:20
zhongkechen
approved these changes
Jun 30, 2026
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.
Issue #, if available:
Description of changes: We have a bug with nested child execution's spans colliding with parent execution's spans. Since the _X_AMZN_TRACE_ID is propagated on the backend, child invocations are receiving the same _X_AMZN_TRACE_ID as the parent. Since we deterministically generate the spanIds using the operationId, a child invocation will currently have identical operationId and thus spanID as the parent execution leading to collisions because previously emitted spans for the parent are being overwritten.
We amend the deterministic span id generation by generating the spanId using a combination of the durableExecutionArn and the operationId. One quirk this does not solve is that the nested child execution from our "invoke" operation will not be naturally nested under the invoke span in the parent. By design, a child execution does not have any information on its parent execution. However, the child execution will be visible under the same traceId as a separate invocation and lambda function. Since it's the same trace, you'll at least be able to locate the related child invoke.
I'll follow this PR up with integration tests for this case as well as some integration tests changes.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.