Repository navigation
[Bug]: enabling both OTel views is accepted without mutual-exclusion validation #758
Description
Expected Behavior
At most one durable OTel view should be active for a handler invocation. InvocationOtelPlugin and ExecutionOtelPlugin are alternative views of the same execution and must not run together.
Reject the unsupported combination during configuration/registration with a clear diagnostic naming both views and explaining that the caller must keep one. Preserve valid single-view configurations and unrelated instrumentation plugins.
Actual Behavior
The current registration path accepts both built-in OTel views:
DurableConfig.Builder.withPlugins(...)accepts both instances; it checks null entries but does not enforce OTel-view exclusivity.DynamicPluginLoaderloads each requested provider and appends explicitly configured plugins. It rejects repeated provider names, butotel-invocationandotel-executionare different valid names.PluginRunnerretains the complete list and invokes every plugin's hooks in registration order. Each OTel view manages its own Workflow/Invocation spans and operation-parent model, so combining them can emit duplicate telemetry and competing context/log-correlation state.
Source inspected at d3208f2e759d3c79e84b46f53c2eb11fb7fe4c09:
- Explicit registration accepts the plugin list.
- Dynamic registration combines both paths; duplicate-name checks are insufficient.
- Runner retains all instances and dispatches every hook.
- Execution view materializes Workflow; Invocation view also materializes Workflow.
Steps to Reproduce
This report is based on source inspection. The following validation recipe has not been executed for this report:
-
Configure a recording OpenTelemetry provider with an in-memory exporter and sampling enabled; avoid an explicit upstream
Sampled=0suppressing the spans under test. -
Register both plugins explicitly:
DurableConfig.builder() .withPlugins(new InvocationOtelPlugin(), new ExecutionOtelPlugin()) .build();
-
Run a handler containing one durable step through terminal completion. Observe that registration accepts both views and both receive hooks. Capture raw exported spans before backend deduplication.
-
With the providers available on the class path, repeat using:
DURABLE_EXECUTION_PLUGINS=otel-invocation,otel-execution -
Repeat with one view explicit and the other selected through the environment, then reverse their order.
Expected: a clear configuration diagnostic prevents both views from running. Current source accepts the combination; duplicate emission and context/MDC restoration should be pinned by focused runtime regression tests.
SDK Version
Current main source at d3208f2e759d3c79e84b46f53c2eb11fb7fe4c09.
Java Version
Not recorded: source inspection only; no new Java runtime reproduction was run for this report.
Is this a regression?
Unknown; no last working version with OTel-view exclusivity enforcement has been established.
Last Working Version
None identified.
Acceptance Criteria
- Document that the two durable OTel views are mutually exclusive, including how to choose one.
- Validate the explicit, dynamic/environment, and mixed registration paths after resolving the effective configuration. Cover both registration orders.
- Reject the combination before either view begins emitting telemetry, with a diagnostic naming the conflicting views. If a different fail-safe policy is selected, document and test it; silently running both is not acceptable.
- Keep zero-OTel-plugin configurations, either single view, and a single OTel view combined with unrelated plugins valid.
- Use reusable exclusivity/registration metadata or an equivalent mechanism that does not require the core SDK to depend on OTel implementation classes. Checking duplicate provider names alone cannot reject two distinct views.
- Test raw exports and context restoration: no duplicate Workflow/Invocation records from competing views, no conflicting operation parents, and no ended or other-view span left active for user logs/spans.
- Cover the initial invocation and suspension/resume, including success and failure, without changing durable operation sequencing or replay behavior.
- Apply the same constraint to any factory-based registration introduced by the plugin lifecycle migration; changing instance lifetime does not make the two views compatible.
Additional Context
- Existing cross-SDK report: [otel] Allow only one OTel plugin at a time: document and validate aws-durable-execution-sdk-python#652
- This is a configuration-validation defect and does not require LMI or concurrent Lambda invocations.
- Python [maven]: Bump software.amazon.awssdk:bom from 2.53.1 to 2.54.2 #652 includes a Python-specific attach/detach ordering failure. This report does not claim that exact failure was reproduced in this language; validate context cleanup through this SDK's own lifecycle.
- Align the diagnostic, supported combinations, documentation, and conformance expectations across JavaScript, Java, and Python.
Activity